2. Who is this guy?
Nick Bailey
nick@datastax.com
@nickmbailey
3. Clojure at DataStax
OpsCenter - Monitoring tool for Apache Cassandra
Server agents written in clojure
Agent communication done using http ( Ring and Compojure)
5. Ok, What is Ring?
https://github.com/mmcgrana/ring
“Ring is a Clojure web applications library inspired by
Python's WSGI and Ruby's Rack. By abstracting the details of
HTTP into a simple, unified API, Ring allows web applications
to be constructed of modular components that can be shared
among a variety of applications, web servers, and web
frameworks.”
10. Code or GTFO
(ns compojure-talk.core
(:use ring.adapter.jetty))
; Middleware Uppercase the response
(defn wrap-upcase [app]
(fn [req] from the handler
(let [orig-resp (app req)]
(assoc orig-resp
:body
(.toUpperCase
(:body orig-resp))))))
; Handler
(defn app [req] Basic, ‘Hello World’ Handler
{:status 200
:headers {"Content-Type" "text/html"}
:body "Hello World from Ring"})
(def upcase-app (wrap-upcase app))
; Run the adapter
(run-jetty upcase-app {:port 8080}) Run our adapter
11. But Wait, There’s More
See: ring.middleware
Serve static files -- ring.middleware.file
Browser cookies -- ring.middleware.cookies
User sessions -- ring.middleware.session
And much more: https://github.com/mmcgrana/ring
13. Ok, What about Compojure
From earlier: “It uses a concise DSL to generate Ring handler
functions.”
An easy an concise way to generate the handler part of your ring
application.
14. The Compojure DSL
defroutes
Macro taking a sequence of routes and the code to process
requests that match those routes.
(defroutes app
(<route>)
(<route>)
(<route>)
15. Anatomy of a Route
Each route has 4 components
(<HTTP method> <URI> <Req. Destructuring> <response>)
16. HTTP Method
One of the http method types defined by compojure
GET, POST, PUT, DELETE, HEAD, ANY
(GET <URI> <Req. Destructuring> <response>)
17. URI
Simple the URI this route should match
(GET “/hello” <Req. Destructuring> <response>)
19. Response
How we want to handle the request
(GET “/hello” [] “Hello World from Compojure”)
20. Hello World, Revisited
(ns compojure-talk.core
(:use ring.adapter.jetty))
; Middleware Note we still have our
(defn wrap-upcase [app]
(fn [req] custom middleware
(let [orig-resp (app req)]
(assoc orig-resp
:body
(.toUpperCase
(:body orig-resp))))))
; Handler We use defroutes to
(defroutes app
(GET "/hello" [] "Hello World from Compojure")) create a handler
(def upcase-app (wrap-upcase app))
; Run the adapter
(run-jetty upcase-app {:port 8080})
21. Back to Destructuring
Access to URI parameters and request body
In the basic form, bind parameter maps and body value to local
vars
(GET “/test” {params :params} (println params))
Take full advantage of clojure destructuring
(GET “/hello” {{user :user} :params} (str “Hello” user “!”))
22. URI Destrcturing
Match dynamic URIs
(GET “/hello/:user” [user] (str “Hello” user “!”))
Note: the destructuring syntax above is short for
“{{user :user} :params}”
Also allows for advanced pattern matching in the URI
23. Our Final Hello
(ns compojure-talk.compojure
(:use compojure.core, ring.adapter.jetty, compojure.handler))
(defroutes app
(GET "/hello/:user" [user] (str "Hello " user "!"))
(GET "/hello" {{user :user} :params}
(if user
(str "Hello " user "!")
"Hello from Compojure!")))
; Run the adapter
(run-jetty (site app) {:port 8080})