Web programming in clojure

28
Web Programming in Clojure Barry Demchak CSE294 November 12, 2010

Transcript of Web programming in clojure

Page 1: Web programming in clojure

Web Programming in Clojure

Barry DemchakCSE294

November 12, 2010

Page 2: Web programming in clojure

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

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

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

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

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

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

The “Ring”

http://www.slideshare.net/mmcgrana/ring-web-apps-in-idiomatic-clojure

Page 9: Web programming in clojure

• (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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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