Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Clojure and the Web


Published on

An introduction to the Ring and Compojure libraries for clojure. Presentation from the February meeting of the Austin Clojure Meetup.

Published in: Technology
  • Be the first to comment

Clojure and the Web

  1. 1. Clojure and the Web Nick Bailey
  2. 2. Who is this guy?Nick
  3. 3. Clojure at DataStaxOpsCenter - Monitoring tool for Apache CassandraServer agents written in clojureAgent communication done using http ( Ring and Compojure)
  4. 4. What is Compojure? “Compojure is a small web framework for the Clojure programming language. It uses a concise DSL to generate Ring handler functions.”
  5. 5. Ok, What is Ring? “Ring is a Clojure web applications library inspired by Pythons WSGI and Rubys 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.”
  6. 6. Ring ArchitectureAdaptersHandlersMiddlewareRequest MapResponse Map
  7. 7. AdaptersResponsible for implementing the HTTP protocol.Basically, the server.Don’t worry, you don’t need to write your own Ring uses Jetty
  8. 8. HandlersYour applicationProcess request, return a response
  9. 9. MiddlewareAugment the functionality of a Handler.Can: Modify Requests Modify Responses
  10. 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. 11. But Wait, There’s MoreSee: ring.middleware Serve static files -- ring.middleware.file Browser cookies -- ring.middleware.cookies User sessions -- ring.middleware.session And much more:
  12. 12. Note for Developingring.middleware.reload Automatically reload handler before each request. Allows for easy testing
  13. 13. Ok, What about CompojureFrom earlier: “It uses a concise DSL to generate Ring handlerfunctions.”An easy an concise way to generate the handler part of your ringapplication.
  14. 14. The Compojure DSLdefroutes Macro taking a sequence of routes and the code to process requests that match those routes. (defroutes app (<route>) (<route>) (<route>)
  15. 15. Anatomy of a RouteEach route has 4 components(<HTTP method> <URI> <Req. Destructuring> <response>)
  16. 16. HTTP MethodOne of the http method types defined by compojureGET, POST, PUT, DELETE, HEAD, ANY(GET <URI> <Req. Destructuring> <response>)
  17. 17. URISimple the URI this route should match(GET “/hello” <Req. Destructuring> <response>)
  18. 18. Request DestructuringDynamic URIs, URL Params, POST bodiesWe’ll come back to this(GET “/hello” [] <response>)
  19. 19. ResponseHow we want to handle the request(GET “/hello” [] “Hello World from Compojure”)
  20. 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. 21. Back to DestructuringAccess to URI parameters and request bodyIn the basic form, bind parameter maps and body value to localvars(GET “/test” {params :params} (println params))Take full advantage of clojure destructuring(GET “/hello” {{user :user} :params} (str “Hello” user “!”))
  22. 22. URI DestrcturingMatch 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. 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})
  24. 24. Links
  25. 25. QUESTIONS?