Clojure Ring Tutorial

By Xah Lee. Date: . Last updated: .

This page is WORK IN PROGRESS.

clojure ring. fantastic.

it's got fantastic doc too. read at

i like to write notes myself, even just typing stuff i read. So, here they are. ignore it. You better off read the link above.

4 important concepts.

a clojure map datatype that represents the http request message.
a clojure map datatype that represents the http response message.
a function you define. It takes in a request (map), and returns a response (map).
“middleware” is a function, that takes in a handler function, and returns the same, but add its own headers.

That is the essence of the Ring lib. It captures the http request and response.

if you forgot what http protocol is like, see HTTP Protocol Tutorial

to start, create

 lein new hello-world
 cd hello-world

Add ring-core and ring-jetty-adapter as dependencies in project.clj.

(defproject hello-world "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [ring/ring-core "1.4.0"]
                 [ring/ring-jetty-adapter "1.4.0"]])

download dependencies.

lein deps

Next, edit src/hello_world/core.clj and add a basic handler.

(ns hello-world.core)

(defn handler [request]
  {:status 200
   :headers {"Content-Type" "text/html"}
   :body "Hello World"})

Now we're ready to connect the handler to an adapter. Start an interactive REPL using Leiningen.

lein repl

Then at the REPL, run the Jetty adapter with your handler.

=> (use 'ring.adapter.jetty)
=> (use 'hello-world.core)
=> (run-jetty handler {:port 3000})

A web server will now be running at: http://localhost:3000/

;; example handler
(defn what-is-my-ip [request]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body (:remote-addr request)})