one to rule them all
play

One () to Rule Them All Aaron Bedra Relevance, Inc. Wednesday, - PowerPoint PPT Presentation

One () to Rule Them All Aaron Bedra Relevance, Inc. Wednesday, November 16, 11 I have a double agenda Wednesday, November 16, 11 But first lets talk about Clojure(Script) Wednesday, November 16, 11 We have this great language with rich


  1. One () to Rule Them All Aaron Bedra Relevance, Inc. Wednesday, November 16, 11

  2. I have a double agenda Wednesday, November 16, 11

  3. But first let’s talk about Clojure(Script) Wednesday, November 16, 11

  4. We have this great language with rich data structures Wednesday, November 16, 11

  5. It can help us solve lots of problems Wednesday, November 16, 11

  6. Web problems are included in the set of all problems... Wednesday, November 16, 11

  7. A short aside... Wednesday, November 16, 11

  8. Clojure on the Web 8 Wednesday, November 16, 11

  9. Ring 9 Wednesday, November 16, 11

  10. http endpoints are functions {request} -> handler -> {response} 10 Wednesday, November 16, 11

  11. basic handler (defn hello-world [request] (let [{:keys [request-method uri]} request] {:status 200 request :headers {} keys :body (str "hello, " request-method " " uri)})) response keys 11 Wednesday, November 16, 11

  12. return nil to ignore inputs (defn hello-world [request] (let [{:keys [request-method uri]} request] (when (and (= request-method :get) (= uri "/")) {:status 200 :headers {} :body "The index page"}))) test for whatever you care about 12 Wednesday, November 16, 11

  13. Compojure 13 Wednesday, November 16, 11

  14. a little macro magic later... (defroutes routes (GET "/" [] "The index page")) 14 Wednesday, November 16, 11

  15. running embedded (ns training.web (:use [ring.adapter.jetty :only (run-jetty)] [compojure.core :only (defroutes GET)])) (defroutes routes (GET "/" [] "<h2>Hello World</h2>")) (run-jetty routes {:port 8080 :join? false}) 15 Wednesday, November 16, 11

  16. Middleware 16 Wednesday, November 16, 11

  17. middleware (defn wrap-cookies [handler] (fn [request] (let [request (if (request :cookies) request call original (assoc request :cookies handler (parse-cookies request)))] (-> (handler request) (set-cookies) (dissoc :cookies))))) modify the result 17 Wednesday, November 16, 11

  18. common ring middleware with-params with-keyword-params with-cookies with-multipart with-session 18 Wednesday, November 16, 11

  19. So common that Compojure wraps them for you 19 Wednesday, November 16, 11

  20. Exposing an API (defn api [routes] (-> routes wrap-keyword-params wrap-nested-params wrap-params)) 20 Wednesday, November 16, 11

  21. Exposing a Site (defn site [routes & [opts]] (-> (api routes) (with-opts wrap-multipart-params (:multipart opts)) (with-opts wrap-session (:session opts)))) 21 Wednesday, November 16, 11

  22. html (hiccup) 22 Wednesday, November 16, 11

  23. html elements clojure vector (html [:h1 "hi"]) -> "<h1>hi</h1>" 23 Wednesday, November 16, 11

  24. html attributes clojure map (html [:a {:href "http://clojure.org"} "Clojure"]) <a href="http://clojure.org">Clojure</a> 24 Wednesday, November 16, 11

  25. id, class shortcuts id class follows # follows . (html [:h1#title.main "hi"]) <h1 class="main" id="title">hi</h1> 25 Wednesday, November 16, 11

  26. simple composition mix clojure (defn home [] literals... (layout/home [:ul (map (fn [lab] [:li (make-url lab)]) all)])) (defroutes lab-routes (GET "/" [] (home))) ...with fncalls and call them from routes 26 Wednesday, November 16, 11

  27. composable routing (defroutes lab-routes (GET "/" [] (home)) (GET "/labs/:name" [name] (render-lab name)) (route/files "/") (route/not-found "<h1>Not Found</h1>")) compose routes (def application (-> lab-routes handlers/with-logging)) simple function wrapping 27 Wednesday, November 16, 11

  28. implementation comparison feature clojure impl oo impl endpoint function interfaces, classes request map interfaces, classes response map interfaces, classes cookies map interfaces, classes session map interfaces, classes interfaces, classes, routing functions, macros config, XML interfaces, classes, middleware functions, macros config, XML, AOP 28 Wednesday, November 16, 11

  29. fns are easy to test! (deftest render-the-labs [] (doseq [lab all] (let [url (lab-url lab) resp (application {:request-method :get :uri url})] (is (= {:status 200 :headers {"Content-Type" "text/html; charset=utf-8"}} (select-keys resp [:status :headers])))))) 29 Wednesday, November 16, 11

  30. It turns out there’s actually a lot of ways to solve problems on the web Wednesday, November 16, 11

  31. Except we are a little light in one area Wednesday, November 16, 11

  32. We are all hopelessly polyglot except when it comes to client side browser code Wednesday, November 16, 11

  33. No matter what we use for our backends we all unify on JavaScript* Wednesday, November 16, 11

  34. Why? Wednesday, November 16, 11

  35. Clojure rocks, JavaScript reaches Wednesday, November 16, 11

  36. So we took Clojure on the road Wednesday, November 16, 11

  37. Yep, CoffeeScript already did it Wednesday, November 16, 11

  38. But there’s so much more Wednesday, November 16, 11

  39. ClojureScript has a full Clojure reader Wednesday, November 16, 11

  40. Clojure data is much more powerful than JSON or XML Wednesday, November 16, 11

  41. With ClojureScript you can adopt Clojure data as your wire protocol Wednesday, November 16, 11

  42. And there’s a hidden gem Wednesday, November 16, 11

  43. Closure Wednesday, November 16, 11

  44. ???? Wednesday, November 16, 11

  45. ClojureScript works with Closure’s advanced compiler Wednesday, November 16, 11

  46. But wait, there’s more! Wednesday, November 16, 11

  47. Browser connected REPL Wednesday, November 16, 11

  48. DEMO Wednesday, November 16, 11

  49. Questions? Wednesday, November 16, 11

  50. Additional information • aaron@clojure.com • @abedra • thinkrelevance.com Wednesday, November 16, 11

Recommend


More recommend