Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Clojure Web Development
Search
pschirmacher
June 11, 2013
Programming
660
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Clojure Web Development
pschirmacher
June 11, 2013
More Decks by pschirmacher
See All by pschirmacher
HTTP with Java 8
pschirmacher
0
150
Clojure Reducers
pschirmacher
1
290
Other Decks in Programming
See All in Programming
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
18k
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
200
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
140
Claude Team Plan導入・ガイド
tk3fftk
0
250
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
130
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
570
Foundation Models frameworkで画像分析
ryodeveloper
1
510
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
360
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
1
270
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
210
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
200
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
140
Featured
See All Featured
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
660
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
390
Why Our Code Smells
bkeepers
PRO
340
58k
The SEO identity crisis: Don't let AI make you average
varn
0
520
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
600
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
430
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
920
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Transcript
We'll take care of it. Personally. Clojure Web Development Philipp
Schirmacher | innoQ Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH http://upload.wikimedia.org/wikip Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Clojure http://upload.wikimedia.org/wikipedia/en/1/1a/Clo A practical Lisp
variant for the JVM Functional programming Dynamic Typing Full-featured macro system Bi-directional Java interop Immutable data structures Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Lisp?? Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Lots of irritating silly parentheses
Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Clojure Environment Clojuresque (Gradle) Leiningen
Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH http://www.tbray.org/ongoing/When/200x/2008/09/25/-big/R0010774.jpg.html Rich Hickey Tuesday, June
11, 13
© 2013 innoQ Deutschland GmbH Clojure Crash Course Tuesday, June
11, 13
© 2013 innoQ Deutschland GmbH Generic Data Types Tuesday, June
11, 13
© 2013 innoQ Deutschland GmbH {:name "Clojure" :features [:functional :jvm
:parens] :creator "Rich Hickey" :stable-version {:number "1.5.1" :release "2013/03/10"}} Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Functions Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (:city {:name "innoQ" :city "Monheim"})
> "Monheim" (map inc [1 2 3]) > (2 3 4) (+ 1 2) > 3 Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (fn [x y] (+ x
y)) ((fn [x y] (+ x y)) 1 2) > 3 (def add (fn [x y] (+ x y))) (defn add [x y] (+ x y)) (add 1 2) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (defn activity [weather] (if (nice?
weather) :surfing :playstation)) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (defn make-adder [x] (fn [y]
(+ x y))) (def add-two (make-adder 2)) (add-two 3) > 5 Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Web Development? Tuesday, June 11,
13
© 2013 innoQ Deutschland GmbH app request response data function
Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Ring Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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}) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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>")}) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH static resources request response homepage
Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (defn decorate [webapp] (fn [req]
...before webapp... (webapp req) ...after webapp...)) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (defn decorate [webapp] (fn [req]
(if (static-resource? req) (return-resource req) (webapp req)))) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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)))))) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (defn my-first-homepage [req] ...) (def
webapp (wrap-resource my-first-homepage "public")) (run-jetty webapp {:port 8080}) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (webapp {:uri "/pretty.css" :request-method :get
:headers {}}) > {:status 200 :headers {} :body #<File ...resources/public/pretty.css>} Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH wrap-resource request response my- rst-homepage
wrap- le-info Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (defn homepage [req] ...) (def
webapp (-> homepage (wrap-resource "public") wrap-file-info)) (run-jetty webapp {:port 8080}) (wrap-file-info (wrap-resource homepage "public")) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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>} Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH wrap-resource wrap- le wrap-params wrap-session
wrap-flash wrap-etag wrap-basic-authentication Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH middleware request response handler middleware
routing ... Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Compojure Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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 Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (def get-handler (GET "/hello/:name" [name]
(str "Hello, " name "!"))) (def post-handler (POST "/names" [name] (remember name) (redirect (str "/hello/" name)))) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Digression: Macros Tuesday, June 11,
13
© 2013 innoQ Deutschland GmbH text Compiler bytecode Tuesday, June
11, 13
© 2013 innoQ Deutschland GmbH text Reader Evaluator data structures
bytecode (if true (print "true" (print "false")) “(if true (print "true" (print "false"))” Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH text Reader Evaluator data structures
bytecode (cond (< 4 3) (print "wrong") (> 4 3) (print "yep")) (if (< 4 3) (print "wrong") (if (> 4 3) (print "yep") nil)) cond- Macro (cond (< 4 3) (pri... (> 4 3) (pri... “(cond (< 4 3) (print "wrong") (> 4 3) (print "yep"))” Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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! Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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))) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH text Reader Evaluator data structures
bytecode (GET "/hello" [] "Hello, World!") (fn [req] (if (and (match (:uri req) "/hello") (= (:request-method req) :get)) {:body "Hello, World!" …} nil)) GET- Macro “(GET "/hello" [] "Hello, World!")” Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Back to Compojure... Tuesday, June
11, 13
© 2013 innoQ Deutschland GmbH (def get-handler (GET "/hello/:name" [name]
(str "Hello, " name "!"))) (def post-handler (POST "/names" [name] (remember name) (redirect (str "/hello/" name)))) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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"))) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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))))) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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}) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH middleware request response handler middleware
routing ... JSON HTML Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Hiccup Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH <element attribute="foo"> <nested>bar</nested> </element> [:element]
Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH <element attribute="foo"> <nested>bar</nested> </element> [:element
{:attribute "foo"}] Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH <element attribute="foo"> <nested>bar</nested> </element> [:element
{:attribute "foo"} [:nested]] Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH <element attribute="foo"> <nested>bar</nested> </element> [:element
{:attribute "foo"} [:nested "bar"]] Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH <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>" Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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>" Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (defn render-person [person] [:dl [:dt
"Name"] [:dd (:name person)] [:dt "Age"] [:dd (:age person)]]) (defn people-page [people] [:html [:head [:title "All the people"]] [:body (map render-person people)]]) Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH (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 ...] ...] Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH <div id="my-id" class="class1 class2"> foo
</div> [:div#my-id.class1.class2 "foo"] Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH middleware request response handler middleware
routing ... JSON HTML Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH middleware {} {} handler middleware
routing ... JSON HTML servlet adapter javax.servlet.http. HttpServletRequest javax.servlet.http. HttpServletRespone Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Conclusion Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH :-) ‣ Simple basic concepts
‣ Easy to use ‣ Little code (also in libraries) ‣ Helpful community ‣ Mature eco system Tuesday, June 11, 13
Thank you! We'll take care of it. Personally. © 2012
innoQ Deutschland GmbH Philipp Schirmacher
[email protected]
@pschirmacher Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Backup Tuesday, June 11, 13
© 2013 innoQ Deutschland GmbH Task Libraries HTTP Basics Ring
Routing Compojure Moustache HTML Hiccup Enlive Persistence clojure.java.jdbc Korma Monger Asynchronous Server Aleph JavaScript ClojureScript Tuesday, June 11, 13