Clojure Web Development

Similar documents
Clojure Web Development

Database Applications Recitation 10. Project 3: CMUQFlix CMUQ s Movies Recommendation System

Introduction to J2EE Web Technologies

ACM Crossroads Student Magazine The ACM's First Electronic Publication

Ch-03 Web Applications

Web Container Components Servlet JSP Tag Libraries

SERVLETSTUTORIAL. Simply Easy Learning by tutorialspoint.com. tutorialspoint.com

N2O Most Powerful Erlang Web

CSc31800: Internet Programming, CS-CCNY, Spring 2004 Jinzhong Niu May 9, Java Servlets

Servlets. Based on Notes by Dave Hollinger & Ethan Cerami Also, the Online Java Tutorial by Sun

Please send your comments to:

Cours. Client/serveur avancé en Java (servlets, RMI, etc.) M.M.F.A.I. François Bourdoncle

INSIDE SERVLETS. Server-Side Programming for the Java Platform. An Imprint of Addison Wesley Longman, Inc.

PA165 - Lab session - Web Presentation Layer

10. Java Servelet. Introduction

Pure server-side Web Applications with Java, JSP. Application Servers: the Essential Tool of Server-Side Programming. Install and Check Tomcat

Frontend- Entwicklung mit React/Reacl. Michael

CIS 455/555: Internet and Web Systems

Visa Checkout September 2015

Java 2 Web Developer Certification Study Guide Natalie Levi

INTRODUCTION TO WEB TECHNOLOGY

Outline. Lecture 9: Java Servlet and JSP. Servlet API. HTTP Servlet Basics

A detailed walk through a CAS authentication

Table of Contents. Open-Xchange Authentication & Session Handling. 1.Introduction...3

HTTP Response Splitting

Class Focus: Web Applications that provide Dynamic Content

People Data and the Web Forms and CGI CGI. Facilitating interactive web applications

Managing Data on the World Wide-Web

Manual. Programmer's Guide for Java API

CTIS 256 Web Technologies II. Week # 1 Serkan GENÇ

Intro to Web Programming. using PHP, HTTP, CSS, and Javascript Layton Smith CSE 4000

Java and Web. WebWork

Modern Web Development From Angle Brackets to Web Sockets

WIRIS quizzes web services Getting started with PHP and Java

The Decaffeinated Robot

Drupal CMS for marketing sites

11.1 Web Server Operation

Oracle Hyperion Financial Management Developer and Customization Guide

Java Web Programming. Student Workbook

2.8. Session management

ULTEO OPEN VIRTUAL DESKTOP OVD WEB APPLICATION GATEWAY

CSC 551: Web Programming. Spring 2004

Startup guide for Zimonitor

Servlet 3.0. Alexis Moussine-Pouchkine. mercredi 13 avril 2011

The HTTP Plug-in. Table of contents

APM for Java. AppDynamics Pro Documentation. Version 4.0.x. Page 1

HOST EUROPE CLOUD STORAGE REST API DEVELOPER REFERENCE

Traitware Authentication Service Integration Document

Cloud Elements! Events Management BETA! API Version 2.0

Introduction to Web Technologies

Comparing Dynamic and Static Language Approaches to Web Frameworks

Arjun V. Bala Page 20

1.Remote Procedure Call Basics Requests Types Response Strategies/Goals FAQ...

Web Application Programmer's Guide

Outline Definition of Webserver HTTP Static is no fun Software SSL. Webserver. in a nutshell. Sebastian Hollizeck. June, the 4 th 2013

The Web: some jargon. User agent for Web is called a browser: Web page: Most Web pages consist of: Server for Web is called Web server:

Remote Access API 2.0

CIS 192: Lecture 10 Web Development with Flask

The full setup includes the server itself, the server control panel, Firebird Database Server, and three sample applications with source code.

Chapter 27 Hypertext Transfer Protocol

Servlet and JSP Filters

2. Follow the installation directions and install the server on ccc

Programming Autodesk PLM 360 Using REST. Doug Redmond Software Engineer, Autodesk

CIS 192: Lecture 10 Web Development with Flask

Configure a SOAScheduler for a composite in SOA Suite 11g. By Robert Baumgartner, Senior Solution Architect ORACLE

Modern Web Application Framework Python, SQL Alchemy, Jinja2 & Flask

The Other mod_rails: Easy Rails Deployment with JRuby. Nick Sieger Sun Microsystems, Inc

Oracle Hyperion Financial Management Custom Pages Development Guide

Web Applications. For live Java training, please see training courses at

Cloud Elements ecommerce Hub Provisioning Guide API Version 2.0 BETA

Web development... the server side (of the force)

Application layer Web 2.0

Login with Amazon. Getting Started Guide for Websites. Version 1.0

CHAPTER 5. Java Servlets

JSP Java Server Pages

Agenda. Summary of Previous Session. Application Servers G Session 3 - Main Theme Page-Based Application Servers (Part II)

An Overview of Java. overview-1

CS506 Web Design and Development Solved Online Quiz No. 01

Controlling Web Application Behavior

Network Technologies

No no-argument constructor. No default constructor found

Intellicus Single Sign-on

XML Processing and Web Services. Chapter 17

Java Servlet Tutorial. Java Servlet Tutorial

Listeners se es. Filters and wrappers. Request dispatchers. Advanced Servlets and JSP

CHAPTER 9: SERVLET AND JSP FILTERS

Java EE 6 New features in practice Part 3

SnapLogic Salesforce Snap Reference

AJAX and JSON Lessons Learned. Jim Riecken, Senior Software Engineer, Blackboard Inc.

Distribution and Integration Technologies

Web Development using PHP (WD_PHP) Duration 1.5 months

Transcription:

Clojure Web Development Philipp Schirmacher Stefan Tilkov innoq We'll take care of it. Personally.

http://www.innoq.com 2011 innoq Deutschland GmbH

http://upload.wikimedia.org/wikip 2011 innoq Deutschland GmbH

http://upload.wikimedia.org/wikipedia/en/1/1a/clo Clojure A practical Lisp variant for the JVM Functional programming Dynamic Typing Full-featured macro system Concurrent programming support Bi-directional Java interop Immutable persistent data structures 2011 innoq Deutschland GmbH

Lisp?? 2011 innoq Deutschland GmbH

Lots of irritating silly parentheses? 2011 innoq Deutschland GmbH

2011 innoq Deutschland GmbH

2011 innoq Deutschland GmbH http://xkcd.com/297/

2011 innoq Deutschland GmbH http://www.flickr.com/photos/nicolasrolland/3063007013/

Rich Hickey 2011 innoq Deutschland GmbH http://www.tbray.org/ongoing/when/200x/2008/09/25/-big/r0010774.jpg.html

Clojure Environment Clojuresque (Gradle) Leiningen 2011 innoq Deutschland GmbH

Data structures Numbers Strings 2 3 4 0.234 3/5-2398989892820093093090292321 "Hello" "World" Characters \a \b \c Keywords Symbols Regexps Lists Vectors Maps Sets :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"} 2011 innoq Deutschland GmbH

Syntax 2011 innoq Deutschland GmbH

You ve just seen it Rich Hickey 2011 innoq Deutschland GmbH

Generic Data Types

{:name "Clojure" :features [:functional :jvm :parens] :creator "Rich Hickey" :stable-version {:number "1.4" :release "2012/04/18"}}

Functions

(+ 1 2) > 3 (:city {:name "innoq" :city "Monheim"}) > "Monheim" (map inc [1 2 3]) > (2 3 4)

(defn activity [weather] (if (nice? weather) :surfing :playstation))

(defn make-adder [x] (fn [y] (+ x y))) (def add-two (make-adder 2)) (add-two 3) > 5

Web Development?

request objects app object response

public interface Servlet { void init(servletconfig servletconfig) throws ServletException; ServletConfig getservletconfig(); void service(servletrequest servletrequest, ServletResponse servletresponse) throws ServletException, IOException; String getservletinfo(); } void destroy();

public interface HttpServletRequest extends ServletRequest { public String getauthtype(); public Cookie[] getcookies(); public Enumeration<String> getheaders(string name); public Enumeration<String> getheadernames(); public String getmethod(); public String getquerystring(); public String getremoteuser(); public HttpSession getsession(boolean create); public boolean authenticate(httpservletresponse response) throws IOException,ServletException;... public void login(string username, String password) throws ServletException;

public interface HttpServletResponse extends ServletResponse { public void addcookie(cookie cookie); public boolean containsheader(string name); public void senderror(int sc, String msg) throws IOException; public void sendredirect(string location) throws IOException; public void setdateheader(string name, long date); public void adddateheader(string name, long date); public void setheader(string name, String value); public void addheader(string name, String value); public void setstatus(int sc);... public int getstatus();

request data app function response

Ring

(defn hello-world-app [req] {:status 200 :headers {"Content-Type" "text/plain"} :body "Hello, World!"}) (hello-world-app {:uri "/foo" :request-method :get}) > {...} (run-jetty hello-world-app {:port 8080})

(defn my-first-homepage [req] {:status 200 :headers {"Content-Type" "text/html"} :body (str "<html><head>" "<link href=\"/pretty.css\"...>" "</head><body>" "<h1>welcome to my Homepage</h1>" (java.util.date.) "</body></html>")})

request response static resources homepage

(defn decorate [webapp] (fn [req]...before webapp... (webapp req)...after webapp...))

(defn decorate [webapp] (fn [req] (if (static-resource? req) (return-resource req) (webapp req))))

(defn wrap-resource [handler root-path] (fn [request] (if-not (= :get (:request-method request)) (handler request) (let [path (extract-path request)] (or (resource-response path {:root root-path}) (handler request))))))

(defn my-first-homepage [req]...) (def webapp (wrap-resource my-first-homepage "public")) (run-jetty webapp {:port 8080})

(webapp {:uri "/pretty.css" :request-method :get :headers {}}) > {:status 200 :headers {} :body #<File...resources/public/pretty.css>}

request response wrap-file-info wrap-resource my-first-homepage

(defn homepage [req]...) (def webapp (-> homepage (wrap-resource "public") wrap-file-info)) (wrap-file-info (wrap-resource homepage "public")) (run-jetty webapp {:port 8080})

(webapp {:uri "/pretty.css" :request-method :get :headers {}}) > {:status 200 :headers {"Content-Length" "16" "Last-Modified" "Thu, 14 Jun..." "Content-Type" "text/css"} :body #<File...resources/public/pretty.css>}

wrap-resource wrap-file wrap-params wrap-session wrap-flash wrap-etag wrap-basic-authentication

request response middleware... middleware routing handler

Compojure

(def get-handler (GET "/hello" [] "Hello, World!")) (get-handler {:request-method :get :uri "/hello"}) > {:body "Hello, World!"...} (get-handler {:request-method :post :uri "/hello"}) > nil

(def get-handler (GET "/hello/:name" [name] (str "Hello, " name "!"))) (def post-handler (POST "/names" [name] (remember name) (redirect (str "/hello/" name))))

Digression: Macros

text Compiler bytecode

text Reader data structures Evaluator bytecode (if true (print "true" (print "false")) (if true (print "true" (print "false"))

text Reader data structures Evaluator bytecode (cond (cond (< 4 3) (print "wrong") (< 4 3) (pri... (print "wrong") (> 4 3) (print "yep")) (> 4 3) (pri... (print "yep")) cond- Macro (if (< 4 3) (print "wrong") (if (> 4 3) (print "yep") nil))

(defmacro my-cond [c1 e1 c2 e2] (list 'if c1 e1 (list 'if c2 e2 nil))) (my-cond false (println "won't see this") true (println "it works!")) it works!

(defmacro my-cond [c1 e1 c2 e2] `(if ~c1 ~e1 (if ~c2 ~e2 nil))) (my-cond false (println "won't see this") true (println "it works!")) it works!

text data Reader Evaluator structures bytecode (GET "/hello" [] (GET "/hello" [] "Hello, World!") "Hello, World!") (fn [req] GET- Macro (if (and (match (:uri req) "/hello") (= (:request-method req) :get)) {:body "Hello, World!" } nil))

Back to Compojure...

(def get-handler (GET "/hello/:name" [name] (str "Hello, " name "!"))) (def post-handler (POST "/names" [name] (remember name) (redirect (str "/hello/" name))))

(defroutes todo-app (GET "/todos" [] (render (load-all-todos))) (GET "/todos/:id" [id] (render (load-todo id))) (POST "/todos" {json-stream :body} (create-todo (read-json (slurp json-stream))) (redirect "/todos")))

(defroutes more-routes (context "/todos/:id" [id] (DELETE "/" [] (delete-todo id) (redirect "/todos")) (PUT "/" {json-stream :body} (update-todo (read-json (slurp json-stream))) (redirect (str "/todos/" id)))))

(defroutes complete-app todo-app more-routes (not-found "Oops.")) (def secure-app (wrap-basic-authentication complete-app allowed?)) (run-jetty (api secure-app) {:port 8080})

request response middleware... middleware routing JSON HTML handler

Hiccup

<element attribute="foo"> <nested>bar</nested> </element> [:element]

<element attribute="foo"> <nested>bar</nested> </element> [:element {:attribute "foo"}]

<element attribute="foo"> <nested>bar</nested> </element> [:element {:attribute "foo"} [:nested]]

<element attribute="foo"> <nested>bar</nested> </element> [:element {:attribute "foo"} [:nested "bar"]]

<html> <head><title>foo</title></head> <body><p>bar</p></body> </html> (def hiccup-example [:html [:head [:title "Foo"]] [:body [:p "Bar"]]]) (html hiccup-example) > "<html>...</html>"

(def paul {:name "Paul" :age 45}) (defn render-person [person] [:dl [:dt "Name"] [:dd (:name person)] [:dt "Age"] [:dd (:age person)]]) (html (render-person paul)) > "<dl><dt>name</dt><dd>paul</dd>...</dl>"

(defn update [{:keys [id text author time]}] (list [:img.avatar {:src (avatar-uri author) :alt author}] [:div.content text] [:div.meta [:span.author (link-to (str "?author=" author) author)] [:span.time (link-to (str "/" id) time)]])) (defn list-page [items next request] (common/layout [:div [:ul.updates (map (fn [item] [:li.post (update item)]) items)]]))

(link-to "http://www.innoq.com" "click here") > [:a {:href "http://www.innoq.com"} "click here"] (form-to [:post "/login"] (text-field "Username") (password-field "Password") (submit-button "Login")) > [:form {:action "POST"...} [:input...]...]

<div id="my-id" class="class1 class2"> foo </div> [:div#my-id.class1.class2 "foo"]

request response middleware... middleware routing JSON HTML handler

javax.servlet.http. HttpServletRequest javax.servlet.http. HttpServletRespone servlet adapter {} {} middleware... middleware routing JSON HTML handler

Noir

www.webnoir.org Integration of Ring/Compojure/Hiccup defpage for defining routes Some middleware preconfigured Parameter parsing, static resources, 404 page etc. Helpers for form validation etc. Auto reload in dev mode

Demo

Conclusion

:-) Simple basic concepts Easy to use Little code (also in libraries) Helpful community Mature eco system

Thank you! Philipp Schirmacher philipp.schirmacher@innoq.com Stefan Tilkov stefan.tilkov@innoq.com @stilkov We'll take care of it. Personally.

Backup

Task HTTP Basics Routing HTML Persistence Libraries Ring Compojure Moustache Hiccup Enlive clojure.java.jdbc Korma Asynchronous Server JavaScript Micro Framework Monger Aleph ClojureScript Ringfinger Noir

Lots of other cool stuff Persistent data structures Sequences Support for concurrent programming Destructuring List comprehensions Metadata Optiional type information Multimethods Pre & Post Conditions Records/Protocols Extensive core and contrib libraries 2011 innoq Deutschland GmbH