Download - Web programming in clojure
![Page 1: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/1.jpg)
Web Programming in Clojure
Barry DemchakCSE294
November 12, 2010
![Page 2: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/2.jpg)
Agenda
• Different REPLs– Eclipse with Counterclockwise– Leiningen
• Compojure Web Framework– Application structure– Framework execution model– High level walkthrough– Addons
• Alternate Frameworks
![Page 3: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/3.jpg)
REPL with Eclipse
• http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Eclipse_and_Counterclockwise
• Install Counterclockwise– Plugin for Eclipse– Create and run simple Clojure project
(firstClojureProject)– Run REPL in console window
• Install the labrepl project (and git/maven)– Good online tutorial
![Page 4: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/4.jpg)
REPL with Leiningen (“lein”)
• First, install Leiningen – a build tool for Clojure– http://www.assembla.com/wiki/show/clojure/Ge
tting_Started_with_Leiningen– Installation downloads itself
• Use Lein to create a project– Create .clj project file– Use editor to add dependencies– Use Lein to satisfy dependencies– Use Lein to start a REPL
https://github.com/weavejester/compojure/wiki/Getting-Started
![Page 5: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/5.jpg)
Agenda
• Different REPLs– Eclipse with Counterclockwise– Leiningen
• Compojure Web Framework– Application structure– Framework execution model– High level walkthrough– Addons
• Alternate Frameworks
![Page 6: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/6.jpg)
Compojure ComponentsCompojure Web App
Ring
Clout Hiccup
Middleware
«uses»
«call»
«call»
Handler«call»
«uses»
Abstract HTTP as {request} and {response}
Enhance {request} and route to user-defined handler
Transform {request} into {response}
Compojure component
Application component
DSL for writing HTML
![Page 7: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/7.jpg)
Compojure Execution Model
What is a “handler”?
• {request} is a map– :server-port 80– :server-name “127.0.0.1”– :remote-addr “127.0.0.1”– :uri “/”– :scheme :http– :headers {}– :request-method :get
• {response} is a map– :status 200
– :headers {:X-lang “Clojure” :X-Framework “Compojure”}
– :body “Hello world”
{request} handler {response}
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?http://efreedom.com/Question/1-3488353/Big-Idea-Behind-Compojure-Routes#3490479
Preview: Simplifying handler construction is Compojure’s key value proposition
![Page 8: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/8.jpg)
The “Ring”
http://www.slideshare.net/mmcgrana/ring-web-apps-in-idiomatic-clojure
![Page 9: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/9.jpg)
• (ns example-app (:use compojure.server.jetty))
• (defn hello-world [request] {:status 200 :headers {}
:body "Hello World"}) • (run-server
{:port 8080} "/*"
(servlet hello-world))
A Simple Servlet Using Ring
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?
![Page 10: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/10.jpg)
Getting Started with Compojure
• https://github.com/weavejester/compojure/wiki/Getting-Started
• Use lien to create a project and dependencies
![Page 11: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/11.jpg)
Agenda
• Different REPLs– Eclipse with Counterclockwise– Leiningen
• Compojure Web Framework– Application structure– Framework execution model– High level walkthrough– Addons
• Alternate Frameworks
![Page 12: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/12.jpg)
A Simple Compojure Web Server
• (ns hello-www.core (:use compojure.core)
(:require [compojure.route :as route]))• (defroutes example
(GET "/" [] "<h1>Hello World Wide Web!</h1>") (route/not-found "Page not found"))
http://weavejester.github.com/compojure/docs/getting-started.html
![Page 13: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/13.jpg)
Clojure Interlude – Useful Macros• (def hello-world (-> hello-world (with-header "X-Lang" "Clojure")
(with-header "X-Framework" "Compojure")))
• (with-header
(with-header
hello-world "X-Lang" "Clojure") "X-Framework" "Compojure")
• (decorate hello-world (with-header "X-Lang" "Clojure") (with-header "X-Framework" "Compojure"))
![Page 14: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/14.jpg)
Compojure Middleware
• (defn with-header[handler header value] (fn [request] (let [response (handler request)] (assoc-in response
[:headers header] value))))
• (decorate hello-world (with-header "X-Lang" "Clojure") (with-header "X-Framework" "Compojure"))
handler & args middleware handler
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?
![Page 15: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/15.jpg)
Compojure Middleware (cont’d)
• Route Handlers return nil if criteria not met– (defn index-route [request]
(if (and (= (:request-method request) :get) (= (:uri request) "/")) {:status 200 :headers {} :body "The index page"))
– (def index-route (GET “/” “The index page”))
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?
![Page 16: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/16.jpg)
Route Components
Route
HTTPMethod
ResponseFunction
URIPattern
DestructuringForm
HTTP command to match
Pattern of URI to match
Extract attributes into local values
Generate response
![Page 17: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/17.jpg)
Index Routes
• (def index-route (GET "/" "The index page"))
• … (GET "/product/:id" (str "You chose product: " (-> request :route-params :id)))
• … (GET #"/product/(\d+)" (str "You chose product: " ((:route-params request) 0)))
Method macro
(GET, PUT, POST …)
Variable capture
Regular
expression matching
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?
![Page 18: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/18.jpg)
Index Routes (cont’d)
• (def echo-typed-url-route (GET "*"
{:keys [scheme server-name server-port uri]}
(str (name scheme) "://" server-name ":“ server-port uri)))
• (defroutes main-routes (POST "/save" {form-params :form-params} (str form-params))
http://efreedom.com/Question/1-3488353/Big-Idea-Behind-Compojure-Routes#3490479
Destructuring
defroutes wraps wrap-params,
wrap-cookies around handler
![Page 19: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/19.jpg)
Destructuring and Local Bindings
• Additional functions update namespace local vars– with-params (:params)– with-cookies (:cookies)– with-multipart– with-session (:session)– with-stacktrace
• Many more documented at http://v-182-163-94-96.ub-freebit.net:8080/docs/api
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?
![Page 20: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/20.jpg)
Response Values
• Base class - {:status 200, :headers {}}• Modification depends on class of modifier
– Integer sets status code– String adds to response body– ISeq, File, and InputStream set response body– URL opens stream and sets response body– Map merges into return value map– Fn produces response from request & response maps– IPersistentVector updates response map
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?
![Page 21: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/21.jpg)
Response Value Examples
• …(GET “/” “Index page”)• …(ANY “*” [404 “Page not found”])• …(GET “/image”
(File. “./public/image.png”))• …(GET “/new-product”
(if product-released? “Cool!” :next))• …(GET “/map-example” {:body “Hi there!”})
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?
![Page 22: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/22.jpg)
HTML Compojure (Hiccup)
• [:h1 {:id “title”} “Hello”] [:h1#id “title” “Hello”]
• [:div (list “Hello” “ Ingolf”)]
• [:div [:span “Hello”] [:span “ Ingolf”]]
{tag attribute-map content}
• <h1 id=“title”>Hello</h1>
• <div>Hello Ingolf</div>
• <div><span>Hello</span><span>Ingolf</span>
</div>
Clojure HTML
http://groups.google.com/group/compojure/msg/9b9c01a737242b58?
![Page 23: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/23.jpg)
Agenda
• Different REPLs– Eclipse with Counterclockwise– Leiningen
• Compojure Web Framework– Application structure– Framework execution model– High level walkthrough– Addons
• Alternate Frameworks
![Page 24: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/24.jpg)
Compojure Addons
• Sandbar– Session and flash as a global map– Authorization and authentication (form-based)– Forms and form validation
https://github.com/brentonashworth/sandbar
![Page 25: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/25.jpg)
Other Web Frameworks• Enlive
– light weight, non-inference routing• Webjure
– light weight, provides routing and parsing on top of Java servlets, Clojure Page Templates
• Conjure– Rails-like framework for Clojure
• Moustache– a micro web framework/internal DSL to wire Ring handlers and
middlewares• Funkyweb
– ring based framework with route inferencehttps://github.com/cgrand/moustache
https://github.com/tatut/Webjurehttp://www.lshift.net/blog/2010/02/27/a-simple-web-application-in-clojure-using-ring-and-enlive
http://groups.google.com/group/clojure/browse_thread/thread/657adc458151e79a/5dfb6362542cf124
![Page 26: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/26.jpg)
Enlive Example(ns sprout.core)
(defn router [req] (condp = (:uri req) "/error" {:status 404
:headers {"Content-Type" "text/html"} :body (str "Error")}
"/info" {:status 200 :headers {"Content-Type" "text/html"} :body (str "Ring on " (:server-name req)) }
{:status 200 :headers {"Content-Type" "text/html"} :body (str "Welcome")}))
(defn app [req] (router req)) http://www.lshift.net/blog/2010/02/27/a-simple-web-application-in-clojure-using-ring-and-enlive
![Page 27: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/27.jpg)
Questions
• Why is Compojure named Compojure?• What are the requirements of the underlying Java-
based web server to support?– Scalability– Extensibility
• How would Compojure participate in web standards?– Web Services (non-Rest)– WS-*
• In the long run, does Compojure need Java?• Does Java need Compojure?
![Page 28: Web programming in clojure](https://reader030.vdocument.in/reader030/viewer/2022020314/58ed66511a28abaf248b45a7/html5/thumbnails/28.jpg)
Other References• Clojure Web Development with Ring http://
mmcgrana.github.com/2010/03/clojure-web-development-ring.html• Compojure: Clojure Web Framework https://
github.com/blog/308-compojure-clojure-web-framework• How do you make a web application in Clojure? http://
stackoverflow.com/questions/167262/how-do-you-make-a-web-application-in-clojure• Introduction to the Compojure web Framework http://
groups.google.com/group/clojure/browse_frm/thread/448865254f9bd293?pli=1• mmcgrana’s ring at master https://github.com/mmcgrana/ring• weavejester‘s compojure at master https://github.com/weavejester/compojure• weavejester’s hiccup at master https://github.com/weavejester/hiccup• WEB DEVELOPMENT – Mature Clojure web frameworks http://
efreedom.com/Question/1-3551805/Mature-Clojure-Web-Frameworks• arbscht‘s clout at string-keys https://github.com/arbscht/clout/tree/string-keys• cgrand‘s enlive at master https://github.com/cgrand/enlive