Skip to content
draganr edited this page Apr 21, 2012 · 30 revisions

The simplest way to get started with Compojure is to use Leiningen, a popular Clojure build tool. If you haven't already, download and install Leiningen.

Once Leiningen is installed, use it to create a new Clojure project:

$ lein new hello-www
$ cd hello-www

This will create a basic project skeleton.

Next, update the project.clj file in the project directory and add a dependency for Compojure:

(defproject hello-www "1.0.0-SNAPSHOT"
  :description "A Compojure 'Hello World' application"
  :dependencies [[org.clojure/clojure "1.2.1"]
                 [compojure "1.0.1"]])

Now you’re ready to write the application. Put the following code into src/hello_www/core.clj:

(ns hello-www.core
  (:use compojure.core)
  (:require [compojure.route :as route]
            [compojure.handler :as handler]))

(defroutes main-routes
  (GET "/" [] "<h1>Hello World Wide Web!</h1>")
  (route/resources "/")
  (route/not-found "Page not found"))

(def app
  (handler/site main-routes))

This defines a basic Ring handler called app. There's a few things going on in this example, so let's briefly go over what it's doing.

We start by defining three routes:

(defroutes main-routes
  (GET "/" [] "<h1>Hello World Wide Web!</h1>")
  (route/resources "/")
  (route/not-found "Page not found"))

Routes in Compojure cascade down, so it tries to match the top route first:

(GET "/" [] "<h1>Hello World Wide Web!</h1>")

This expression defines a routing function that will match only if the request method is "GET", and the URI is "/". Anything else will cause the route to return nil, and the request will cascade to the next route in the sequence:

(route/resources "/")

This route is generated by a function in the compojure.route namespace. It will look for files in the "resources/public" directory that match the request URI. This allows you to include static files like CSS stylesheets or images in your project.

If there are no matching static resources, the request falls to the third and final route:

(route/not-found "Page not found")

You probably won't be surprised to learn that this returns a 404 response. This route will always match, so it acts as a catch-all route for any request that doesn't match the previous routes.

Once the routes are defined, they are wrapped in the site function:

(def app
  (handler/site main-routes))

This adds a bunch of commonly-used Ring middleware to your routes. Without this, you couldn't access cookies, or form parameters, or work with session variables.

Now that the handler function is defined, we need a way of running it. The easiest way to do this is to add lein-ring as a development dependency in your project.clj file:

(defproject hello-www "1.0.0-SNAPSHOT"
  :description "A Compojure 'Hello World' application"
  :dependencies [[org.clojure/clojure "1.2.1"]
                 [compojure "1.0.1"]]
  :dev-dependencies [[lein-ring "0.6.3"]]
  :ring {:handler hello-www.core/app})

The lein-ring plugin is configured with the :ring key. Here we've told it where the main Ring handler is.

You can now start a development server using Leiningen:

$ lein ring server

The development server will find a free port and open a browser window for you. If you make a change to one of the source files, it will automatically reload it for you.