Saturday 3 October 2015

simple http-kit app with live reloading

Continuing on from my simplest possible http-kit application, I wanted to make it slightly more useful by doing two more things. First, get the app to run with lein run instead of firing up a repl, loading the simple/core file and manually calling (run-server #'app {:port 8080}). Second, get the source code doing live reload.

Lein Run

This is very simple and involves only a little bit of tweaking. Leiningen can be told to run a specific module/function when using lein run. So I made a small tweak to src/simple/core.clj

 (ns simple.core
    (:use [org.httpkit.server :only [run-server]]))

(defn app [req]
  {:status  200
   :headers {"Content-Type" "text/html"}
   :body    "hello HTTP"})

(defn serve[& args]
    (run-server #'app {:port 8080}))

Now I can run lein run -m simple.core/serve and have the application be served. This is nice, however we cannot do any serious development until we have hot reloading of code.

Kill leinigen before going any further though.

Hot Reloading

Hot reloading of code is different to stopping and starting a server (like in django’s server), the code never stops serving requests, instead we just update the code as it’s running. Bottom line is that without this, developing in clojure would be horrific for me. Leinigen is not the fastest thing in the world (because we’re launching the JVM) and the thought of having to stop and restart it everytime I change something is abbhorrent.

Luckily, we only need to make a few small changes to get this functionality. We need to utilse ring’s middleware, so this means updating our dependencies in the project.clj file and the -main function in core.clj.

Here is the updated project.clj file …

(defproject simple "0.0.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [ring/ring-devel "1.4.0"]
                 [ring/ring-core "1.4.0"]
                 [http-kit "2.1.19"]]
  :main "simple.core")

And here is the updated src/simple/core.clj file …

(ns simple.core
  (:use [org.httpkit.server :only [run-server]])
  (:require [ring.middleware.reload :as reload]))

(defn app [req]
  {:status  200
   :headers {"Content-Type" "text/html"}
   :body    "hello HTTP!"})

(defn -main [& args]
    (run-server (reload/wrap-reload #'app) {:port 8080}))

You can see that the only change was to wrap the app up inside the reload/wrap-reload middleware. You can now test this out by running lein run, when it loads you can open up a browser and hit and see the familiar message - “hello HTTP!”. Only this time you can go back to simple/core.clj and update the body to something else “hello world” seems fitting, and when you refresh your browser you’ll see that the running code has been updated.


So now our very simple app can be easily started and the code can be easily reloaded, which means that development is now more fun. However you may have noticed that nothing at all get’s logged to stdout when we’re serving requests. This sucks, so next I’m going to tackle that.

Here’s what’s remaining …

  1. Build the simplest possible http-kit app
  2. App running via lein run and live reloading of source
  3. Logging requests to stdout
  4. Routes with and without parameters
  5. Postgres integration
  6. Writing Tests
  7. Configuring the application to return JSON Responses (coming soon)
  8. A Clojurescript UI (coming soon)
  9. Websockets (coming soon)
  10. Putting your application into production (coming soon)

The full source code can be found on github and I’ve tagged the code for this post as 2.0.1.