clojure workshop: web development

17
Web development by Carlo Sciolla

Upload: sytac

Post on 15-Jul-2015

64 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Clojure Workshop: Web development

Web developmentby Carlo Sciolla

Page 2: Clojure Workshop: Web development

Ring handles HTTP

ring

GET /home

HTTP/1.1 200 OK

your app

Page 3: Clojure Workshop: Web development

Map in, map out

GET /home HTTP/1.1User-Agent: curl/7.37.1Host: 127.0.0.1:4000Accept: *

{:request-method :get :url /home HTTP/1.1 :headers {“User-Agent” ...} ...}

application

{:status 200 :body “Hello, world!” :headers {...} ...}

HTTP/1.1 200 OKContent-Type: text/plain

Hello, world!

Page 4: Clojure Workshop: Web development

Anatomy of a ring handler(defn handler [request] {:status 200 :headers {"Content-Type" "text/plain"} :body "Hello World"})

Following the simplicity of the ring abstraction, ring handlers are plain functions. Compare this to a Java Servlet.

Page 5: Clojure Workshop: Web development

How to run a ring application(ns my.web (:use ring.jetty.adapter))

(defn handler [request] {:status 200 :headers {"Content-Type" "text/plain"} :body "Hello World"})

(run-jetty handler 8080)

You can find ring adapters (-> wrappers) for the most common app servers. Ring will dispatch HTTP requests to your handler.

Page 6: Clojure Workshop: Web development

How to run a ring application; in project.clj::plugins [[lein-ring "0.9.3"]]:ring {:handler hello-world.core/handler}

$ lein ring serverStarted nREPL server on port 45002015-04-20 20:19:37.495:INFO:oejs.Server:jetty-7.6.13.v201309162015-04-20 20:19:37.548:INFO:oejs.AbstractConnector:Started [email protected]:8090Started server on port 8090

An alternative way to start your application is to run it from sources.

Page 7: Clojure Workshop: Web development

How to run a ring application; in project.clj::plugins [[lein-ring "0.9.3"]]:ring {:handler hello-world.core/handler}

$ lein ring uberwarCreated /Users/skuro/demo/target/demo-1.0-standalone.war

If you need a standard packaging, that’s available also.

Page 8: Clojure Workshop: Web development

Filtering with middleware(defn wrap-content-type [handler type] (fn [request] (let [response (handler request)] (assoc-in response [:headers “Content-Type”] type))))

(def wrapped (wrap-content-type handler “text/plain”))

Middleware functions wrap regular handlers to enhance their functionalities. They accept in input a handler plus other arguments, and must return a new handler. Compare them to Servlet Filters.

Page 9: Clojure Workshop: Web development

Compojure to route requests(ns hello-world.core (:require [compojure.core :refer :all] [compojure.route :as route]))

(defn surname [name] ({"Alfred" "Hitchcock"} name))

(defroutes app (GET "/:name" [name] (surname name) (route/not-found "<h1>Page not found</h1>"))

Compojure helps you route request to the correct function depending on the request details. Route matches are attempted in lexical order.

Page 10: Clojure Workshop: Web development

Compojure to route requests(defroutes my-api (context "/api" [] (GET "/people" [] (list-people) (GET "/people/:name" [name] (describe-person name))))

; the above registers handles for these URLs:; /api/people; /api/people/:name

Routes can be grouped together via context, which establishes a common prefix and common destructured parameters.

Page 11: Clojure Workshop: Web development

Middleware to convert to JSON(use '[ring.middleware.json :only [wrap-json-response]] '[ring.util.response :only [response]])

(defn handler [request] (response {:foo "bar"}))

(def app (wrap-json-response handler))

An handler can translate automatically your response bodies into JSON, and will also translate the incoming request bodies into Clojure datastructures.

Page 12: Clojure Workshop: Web development

Questions?

Page 13: Clojure Workshop: Web development

create a JSON-based REST API that provides the following endpoints:

GET /peopleLists the current people. Ex.:[{"id": 0, "name": "Carlo"}]

GET /people/:nameReturns the details of the selected person

POST /peopleAdds a new person. The body is of the form:{"name": "Carlo"}

Exercise time:$ lein new compojure folks

Page 14: Clojure Workshop: Web development

A Clojure DSL for HTML; in your project.clj:dependencies [[hiccup "1.0.5"]]

user=> (use ‘hiccup.core)niluser=> (html [:span {:class "foo"} "bar"])"<span class=\"foo\">bar</span>"

Hiccup is a library that translates Clojure datastructures into HTML.

Page 15: Clojure Workshop: Web development

introduce a home page to manage people via HTML:

GET /

- The HTML contains the list of the current people- The HTML contains a form to create a new person (using the POST

endpoint you created)

Exercise time:Add HTML pages to your app

Page 16: Clojure Workshop: Web development

DemoClojureScript

Page 17: Clojure Workshop: Web development

ThanksCarlo Sciolla CTO

[email protected]+31 6 21205911

mailphone