Future Gadget #8 Code;Blog

(name subject to change)

First Clojure Web Application

Recently I've been playing with Clojure in my free time. This will be part blog post and part instructional as I walk through developing a simple web application.

Clojure Tools

I've installed the following tools for clojure development:

  • Leinengin - a ridiculously easy to use Clojure REPL, build tool, dependency manager, and project automation tool. It will even cut your sandwiches into triangles if that's what you want it to do.
  • Light Table by Chris Granger. At the time of writing this post, Light Table is under development. It's an open source IDE written in ClojureScript that runs on top of node-webkit. Light Table had a sweet kickstarter and the creator is on a mission to transform the way we interact with source code. It's not at all a bad way to start using clojure.

Both of these tools are available on Windows, Linux, and Mac. (But I'm using them on Windows)

Frameworks and Libraries

Web frameworks materialize and are subsequently abandoned to float into the aether at an alarming rate. Maybe it's because we haven't solved the problem that web frameworks are supposed to solve. Maybe nobody can agree on what that problem is or how to solve it. I look forward to writing my own general purpose web framework and abandoning it just to see what it feels like.

Quite refreshingly, however, Clojure web frameworks look like they're on the lightweight side across the board. I'll be developing my example application using the following libraries:

These are all maintained on github primarily by James Reeves. You should definitely read the source code for Hiccup and Compojure.

Hello, Compojure!

I have big plans for this website: I've been perfecting my state of the art algorithm for generating vampire names for years. With this site I will solve the identity crises of angsty teenagers all over the world. Never again will youth agonize over having names that just aren't edgy enough.

First, I type the command lein new vampire-web to create a new lein project using the default template. This creates a nearly empty project. There's also a useful template for compojure applications, but writing the skeleton code out once helps dispel any illusion of wizardry that might come from using a template.

Here's my project definition:

(defproject vampire-web "0.0.1"
  :description "Extreme Vampire Name Generator"

  :dependencies [[org.clojure/clojure "1.5.1"]
                 [ring "1.3.0"]
                 [hiccup "1.0.5"]
                 [compojure "1.1.8"]]

  :plugins [[lein-ring "0.8.11"]]

  :ring {:handler vampire-web.core/app})

The :ring entry configures which handler to have lein-ring start with. (I'm sure there's a way to wire up lein-ring to Light Table. I'll be leaving that adventure for another day.)

And now for my Hello World of compojure and hiccup applications. In core.clj:

(ns vampire-web.core
  (:use compojure.core)
  (:require [hiccup.page :as page])
  (:require ring.middleware.params)
  (:require [compojure.route :as route]))

(defroutes approutes
  (GET "/"   [] 
    (page/html5 [:head [:title "Vampire Name Generator"]]
           [:body
             [:h1 "The Vampire Name Generator"]
             [:form {:method "POST" :action "/bestow-name"}
               [:label "Enter your human name:"] [:br]
               [:input {:type "text" :name "human-name"}]
               [:input {:type "submit" :value "Get Name"}]]]))

  (POST "/bestow-name" [human-name]
    (page/html5 [:head [:title "Your Vampire Name"]]
           [:body
             [:h1 "Your Vampire Name"]
             [:p "Sir " human-name " Van Alucard"]])))

(def app
  (-> approutes
      ring.middleware.params/wrap-params))

My web application has two routes: GET / and POST /bestow-name. Compojure hooks up querystring and post parameters to the variable names in square brackets. However, to make querystring and post parameters available I composed my routes with ring.middleware.params/wrap-params.

I use the lein-ring plugin to start and stop my development server. Type the command lein ring server from your project directory to fire it up and open a browser window. Here's what I see:

My first Vampire name generator Brilliant Vampire name

Alright, now we're talking. I've got compojure and hiccup working to serve a very basic form along with some sweet form post action. (Note: If you aren't seeing parameters in your post routes make sure that you didn't forget wrap-params. It took me a while to figure this out myself because outdated blog posts do not include this detail. Compojure used to automatically apply this middleware for you.)

Conclusion

I'm very happy with the way that Compojure and Hiccup cut down the boilerplate required to build a web application without introducing heavy wizardry. This was my first experience with Clojure but reading through source code and documentation for Hiccup and Compojure wasn't too difficult. To anyone new to Clojure web development, I recommend expanding Compojure macros like route and defroutes and reading up on ring. Also, check out this talk James Reeves gave on compojure. It really let me start solidifying my understanding of Clojure web development.

Where Next

I'll build onto this site in my next post. The codebase is going to get bigger, so I'll need to group functions out into multiple files before I can upgrade the page's aesthetic and name generation algorithm.


Powered by Copland OS Enterprise wired technology.