Clojure Workshop: Web development

Post on 15-Jul-2015

63 views 1 download

transcript

Web developmentby Carlo Sciolla

Ring handles HTTP

ring

GET /home

HTTP/1.1 200 OK

your app

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!

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.

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.

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 SelectChannelConnector@0.0.0.0:8090Started server on port 8090

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

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.

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.

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.

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.

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.

Questions?

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

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.

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

DemoClojureScript

ThanksCarlo Sciolla CTO

carlo.sciolla@sytac.nl+31 6 21205911

mailphone