Sunday, April 04, 2010

My Clojure, Ring, Compojure development setup

I had to search several sources (like this) to get this setup, so I thought it would be useful to summarize my setup here. Unlike most developers, I use five different editors (emacs+slime+swank, IntelliJ IDE, GEdit, e, and Textmate) depending on which computer and OS I am on. I wanted to be able to leave a Compojure based web app running in development mode and have source files refresh regardless of which editor I am using. In the following example, I have two Clojure source files: one with Ring and Compojure code, and one a utility file, containing for this example an extremely useful function foo. Start by creating an empty Leiningen project:
lein new KBSportal
cd KBSportal
Then edit project.clj to look like:
(defproject kbsportal "0.1.0"
:description "test using Compojure for KBSportal.com"
:dependencies
[[compojure "0.4.0-SNAPSHOT"]
[ring/ring-devel "0.2.0-RC2"]
[ring/ring-httpcore-adapter "0.2.0-RC2"]
[ring/ring-jetty-adapter "0.2.0-RC2"]
[ring/ring-servlet "0.2.0-RC2"]]
:main kbsportal)
In the empty src directory create the file kbsportal.clj:
(ns kbsportal
(:use compojure.core
ring.adapter.jetty)
(:use ring.middleware.reload)
(:use ring.middleware.stacktrace)
(:use nlp)) ; nlp.clj is my other source file

(defroutes test-routes
(GET "/" []
(str "<h1>Testing foo: " (foo) "</h1>"))
(ANY "*" []
{:status 404, :body "<h1>Page not found error</h1>"}))

(def app
(-> (var test-routes)
(wrap-reload '(kbsportal))
(wrap-reload '(nlp))
(wrap-stacktrace)))

(defn dev []
(run-jetty #'app {:port 8080}))
and the file nlp.clj:
(ns nlp)

(defn foo [] " - This is from foo.") ; a very useful function!
Notice how I use the Ring wrap-reload function to force checking the date stamp on the two source files and reload them if they are changed. You would not want to check for automatic reloads in a production environment. This is a skeleton project, but in a real project you could add wrap-reload calls for new source files that you add to your project's src directory. To run in development mode, you can type:
lein repl
to start a Clojure repla and then inside the repla load the main source file and run the (dev) function:
(use 'kbsportal)
(dev)
Hit the URL http://localhost:8080 to load the test web page, edit either source file, and reload the web page to see the effects of your edits. This setup provides a quick and effective interactive development environment. If you just use emacs, then for a better alternative look for one of the excellent emacs+slime+swank Compojure-specific tutorials on the web.

1 comment:

Carsten said...

Thanks for this article. I started my first leiningen/compojure project now. :-)