ring: web apps in idiomatic clojure
DESCRIPTION
TRANSCRIPT
RingWeb Apps in Idiomatic Clojure
Mark McGranaghan
January 23, 2010
About Mark
I Bowdoin College ’10
I Clojure user since 2008
I Open source: http://github.com/mmcgrana
Motivation for Ring
I Abstract HTTP
I Write apps in idiomatic Clojure
I Share code across web frameworks
I Deploy on a variety of web servers
I WSGI & Rack
Motivation for Ring
I Abstract HTTP
I Write apps in idiomatic Clojure
I Share code across web frameworks
I Deploy on a variety of web servers
I WSGI & Rack
Motivation for Ring
I Abstract HTTP
I Write apps in idiomatic Clojure
I Share code across web frameworks
I Deploy on a variety of web servers
I WSGI & Rack
Motivation for Ring
I Abstract HTTP
I Write apps in idiomatic Clojure
I Share code across web frameworks
I Deploy on a variety of web servers
I WSGI & Rack
Motivation for Ring
I Abstract HTTP
I Write apps in idiomatic Clojure
I Share code across web frameworks
I Deploy on a variety of web servers
I WSGI & Rack
Motivation for Ring
I Abstract HTTP
I Write apps in idiomatic Clojure
I Share code across web frameworks
I Deploy on a variety of web servers
I WSGI & Rack
The Ring Project
I Spec
I Library
I Ecosystem
The Ring Project
I Spec
I Library
I Ecosystem
The Ring Project
I Spec
I Library
I Ecosystem
The Ring Project
I Spec
I Library
I Ecosystem
Overview of Ring
I Handlers are functions
I that take requests as Clojure maps
I and return responses as Clojure map
I Adapters run handlers on a web server
I Middleware augments handlers
Overview of Ring
I Handlers are functions
I that take requests as Clojure maps
I and return responses as Clojure map
I Adapters run handlers on a web server
I Middleware augments handlers
Overview of Ring
I Handlers are functions
I that take requests as Clojure maps
I and return responses as Clojure map
I Adapters run handlers on a web server
I Middleware augments handlers
Overview of Ring
I Handlers are functions
I that take requests as Clojure maps
I and return responses as Clojure map
I Adapters run handlers on a web server
I Middleware augments handlers
Overview of Ring
I Handlers are functions
I that take requests as Clojure maps
I and return responses as Clojure map
I Adapters run handlers on a web server
I Middleware augments handlers
Overview of Ring
I Handlers are functions
I that take requests as Clojure maps
I and return responses as Clojure map
I Adapters run handlers on a web server
I Middleware augments handlers
“Ring”
Request Map
{:uri <String>
:query-string <String>
:request-method <Keyword>
:headers <IPersistentMap>
:body <InputStream>
... ...}
Response Map
{:status <Integer>
:headers <IPersistentMap>
:body <String, ISeq, File, InputStream>}
Example: Hello World
(defn app [req]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str "Hi from " (:server-name req))})
(use ’ring.adapter.jetty)
(run-jetty app {:port 8080})
Example: Hello World
(defn app [req]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str "Hi from " (:server-name req))})
(use ’ring.adapter.jetty)
(run-jetty app {:port 8080})
Example: Hello World
Example: Stacktraces
(defn app [req]
("o noes"))
(use ’ring.adapter.jetty)
(use ’ring.middleware.stacktrace)
(run-jetty (wrap-stacktrace app) {:port 8080})
Example: Stacktraces
(defn app [req]
("o noes"))
(use ’ring.adapter.jetty)
(use ’ring.middleware.stacktrace)
(run-jetty (wrap-stacktrace app) {:port 8080})
Example: Stacktraces
Example: Static Files
(defn dynamic-app [req]
(...))
(use ’ring.middleware.file)
(use ’ring.middleware.file-info)
(def app
(-> dynamic-app
(wrap-file "public")
(wrap-file-info)))
Example: Static Files
(defn dynamic-app [req]
(...))
(use ’ring.middleware.file)
(use ’ring.middleware.file-info)
(def app
(-> dynamic-app
(wrap-file "public")
(wrap-file-info)))
Example: Testability
(defn my-app [req]
(...))
(deftest not-found-error
(let [req {:uri "/bogus/uri"}
resp (my-app req)]
(is (= 404 (:status resp)))))
Example: Testability
(defn my-app [req]
(...))
(deftest not-found-error
(let [req {:uri "/bogus/uri"}
resp (my-app req)]
(is (= 404 (:status resp)))))
Example: Testability
(defn my-app [req]
(...))
(deftest not-found-error
(let [req {:uri "/bogus/uri"}
resp (my-app req)]
(is (= 404 (:status resp)))))
Ring and Web Frameworks
I Foundation, not replacement
I Avoid duplication and share code
I Compojure, Conjure, Weld all targeting Ring
I Compojure case study
Ring and Web Frameworks
I Foundation, not replacement
I Avoid duplication and share code
I Compojure, Conjure, Weld all targeting Ring
I Compojure case study
Ring and Web Frameworks
I Foundation, not replacement
I Avoid duplication and share code
I Compojure, Conjure, Weld all targeting Ring
I Compojure case study
Ring and Web Frameworks
I Foundation, not replacement
I Avoid duplication and share code
I Compojure, Conjure, Weld all targeting Ring
I Compojure case study
Ring and Web Frameworks
I Foundation, not replacement
I Avoid duplication and share code
I Compojure, Conjure, Weld all targeting Ring
I Compojure case study
Ring Middleware
I ring.middleware.reload: Automaticallyreload namespaces
I ring.middleware.params: Get requestparams as a map
I ring.middleware.cookies: Cookie jarabstraction
Ring Middleware
I ring.middleware.reload: Automaticallyreload namespaces
I ring.middleware.params: Get requestparams as a map
I ring.middleware.cookies: Cookie jarabstraction
Ring Middleware
I ring.middleware.reload: Automaticallyreload namespaces
I ring.middleware.params: Get requestparams as a map
I ring.middleware.cookies: Cookie jarabstraction
Ring Middleware
I ring.middleware.reload: Automaticallyreload namespaces
I ring.middleware.params: Get requestparams as a map
I ring.middleware.cookies: Cookie jarabstraction
Other Components
I ring.util.servlet: If you really want aServlet
I ring.adapter.httpcore: Adapter for HTTPCore library
I ring.handler.dump: See the request map
I ring.examples.*: Runnable examples
Other Components
I ring.util.servlet: If you really want aServlet
I ring.adapter.httpcore: Adapter for HTTPCore library
I ring.handler.dump: See the request map
I ring.examples.*: Runnable examples
Other Components
I ring.util.servlet: If you really want aServlet
I ring.adapter.httpcore: Adapter for HTTPCore library
I ring.handler.dump: See the request map
I ring.examples.*: Runnable examples
Other Components
I ring.util.servlet: If you really want aServlet
I ring.adapter.httpcore: Adapter for HTTPCore library
I ring.handler.dump: See the request map
I ring.examples.*: Runnable examples
Other Components
I ring.util.servlet: If you really want aServlet
I ring.adapter.httpcore: Adapter for HTTPCore library
I ring.handler.dump: See the request map
I ring.examples.*: Runnable examples
Future Work
I Middleware and utility extraction fromframeworks
I Not a framework itself
I More use in production?
I User needs?
Future Work
I Middleware and utility extraction fromframeworks
I Not a framework itself
I More use in production?
I User needs?
Future Work
I Middleware and utility extraction fromframeworks
I Not a framework itself
I More use in production?
I User needs?
Future Work
I Middleware and utility extraction fromframeworks
I Not a framework itself
I More use in production?
I User needs?
Future Work
I Middleware and utility extraction fromframeworks
I Not a framework itself
I More use in production?
I User needs?
Learn More
I http://github.com/mmcgrana/ring
I ring/example/*.clj
I ring/SPEC