Sunday, March 12, 2017

A simple Clojure Hello World application in Google Application Engine's Standard Environment

Over the past couple of days I've poked around through the Google Application Engine (GAE) documentation and getting started tutorials with the intention of getting a simple Clojure based Hello World application. It turns out that it's not that hard. All the code discussed in this blog is available in a github repository if you'd like to take a look.

If you're familiar with Clojure web development, you will likely already know most of this tutorial. To save you time, I will add a star (☆) to sections that are unique to GAE.

If you want to try this example at home, you'll need to create an account on GAE and create a project with an application in their standard environment. The standard environment is sandboxed and quite limited, but it's enough to explore GAE.

When you first sign up, there's a tutorial for creating a Java based Hello World application in your project. It's worth your time to go through that, because then you can switch that project over to Clojure mode later.

To create the Clojure project, I started with the default leiningen template. Then I added necessary dependencies to it, and added some additional configuration to the project.clj file that is required for the lein-ring plugin to create a war file. After that, I wrote the application code, and finally I scripted the remaining steps to deploy the application on GAE.

To create my Clojure project, I simply created a new application with the default leiningen application project, and then I added the following dependencies to it.
[ring/ring-core "1.5.1"]
[ring/ring-servlet "1.5.1"]
[compojure "1.5.2"]
[cheshire "5.7.0"]
Ring is the go-to routing library in Clojure, and you'll need ring-core for that. Additionally, you'll need to interface with the GAE servlet environment once you're running in the GAE environment with ring-servlet. Compojure adds a useful DSL on top of ring routes, and Cheshire is a Clojure wrapper for Jackson, which is a JSON processing library.

After adding the dependencies, I added configuration the project file for lein-ring. Which is a plugin to help you with ring web development.

    :plugins [[lein-ring "0.11.0"]]
    :ring {:handler clojure-gae-quickstart.core/app}

The first line adds the lein-ring plugin to the project, and the second line tells it where your ring routes are so you can run your web application in development mode with lein-ring. This is especially useful, because lein-ring will reload your code by default with each request, so you can make changes to the running server without having to restart.

☆ After configuring lein-ring, I added configuration files for GAE to the war-resources/WEB-INF directory.

    war-resources/WEB-INF/appengine-web.xml   
    war-resources/WEB-INF/logging.properties


☆ appengine-web.xml file is a descriptor that GAE uses when you upload your application. You'll need to change the application tag in that file to match the application name that you have configured in the GAE console. The war-resources directory is used by the lein-ring plugin to add additional resources to the war file when you use lein-ring to create a war file.

Next, I added an index.html to the resources/public folder, and I then wrote the code to the clojure-gae-quickstart.core namespace to duplicate the functionality of the Java getting started example. This code is completely independent of GAE, so I was able to test it and debug it with lein-ring. It's not clear if that would be possible if the code relied on GAE services. I may look into that in the future.

☆ Google provides a script called appcfg.sh in the Java application development kit which can be used to upload an exploded war file and deploy your application. So, you must first create the war file and then unzip it and update the version number in the exploded copy of the appengine-web.xml file to something unique, and finally upload it to Google with the appcfg.sh script. I implemented this with a quick and dirty script, make.sh. It probably wouldn't be that difficult to create a leiningen plugin that built upon what is in the lein-ring plugin to do this, but I wasn't ready to commit to that effort this weekend.

So, while this is all encouraging. There is a downside. What prompted me to start investigating GAE was that they made PostgreSQL available. However, it's currently is in a beta state, and not available to applications in the standard environment. (reference)


I'm not particularly interested in MySQL, or interested in cloud vendor lock in with proprietary storage APIs. So right now, this effort goes on the shelf. I might take a look and see if it's possible to develop v.s. their simulator libraries for their services without running in their test server, but right now I'm not sure if I will.

I hope somebody finds this useful.

Friday, March 10, 2017

Getting Started

Today's random software topic is related to web development in Clojure. Namely, figuring out how to deploy an application to the internet for little cost and little effort.

I've used Digital Ocean (DO) in the past, and it's cheap. However, it's more work than I want to deal with for a hobby project. When I say, "more work than I want to deal with," I don't mean that it's hard to create an application on DO, but over time the effort involved in keeping things up to date gets higher, and I'd like to figure out how to avoid that.

I decided to take a look at Google App Engine tonight. Here are my notes.
Earlier today I saw that they added Postgres to their SQL offerings. Checked out the various price tiers, and it's not clear to me what they mean. I did learn that 5G of space on the smallest instance is less than $10 per month, but no idea how that would perform.
Signed up to try. First off, there’s $300 in credit that’s good for a year. That’s good for experimenting. You can run 28 hours per day of standard app engine instances. So a single one of those is free. These are restricted to Java 7, so have to be careful about what’s going on with that. There’s also a fairly restrictive whitelist of classes that it can run, so that could interfere with library selection. Still worth investigating.
Up next for tomorrow, get a simple hello world app written in Clojure and deployed. At a minimum, it should be able to use Cheshire, will also need to figure out if it can talk to a PostgreSQL instance. I may or may not get to that tomorrow.
Cheers and good night.