Ring Spec (1.5.1)
Ring is an abstraction layer for building HTTP server applications in Clojure. Defines synchronous and asynchronous APIs.
Handlers
Synchronous handler (1 arg):
(fn [request] response)
Asynchronous handler (3 args):
(fn [request respond raise]
(respond response)) ; or (raise exception)
Dual-arity handler:
(fn
([request] response)
([request respond raise] (respond response)))
Middleware
Higher-order functions that augment handlers:
(fn [handler & config-options] enhanced-handler)
Adapters
Start HTTP server with handler and options:
(run-adapter handler options)
(run-adapter handler {:async? true}) ; for async handlers
Request Maps
| Key | Type | Required | Notes |
| ------------------- | ---------------------------------- | -------- | ----- |
|:body |java.io.InputStream | | Request body |
|:character-encoding|String | | DEPRECATED |
|:content-length |String | | DEPRECATED |
|:content-type |String | | DEPRECATED |
|:headers |{String String} | Yes | Lowercase keys; multi-value concat with ,; cookie uses ; |
|:protocol |String | Yes | e.g. "HTTP/1.1" |
|:query-string |String | | After ?, excludes ? |
|:remote-addr |String | Yes | Client or last proxy IP |
|:request-method |Keyword | Yes | :get, :post, etc. |
|:scheme |Keyword | Yes | :http, :https, :ws, :wss |
|:server-name |String | Yes | Server name or IP |
|:server-port |Integer | Yes | Port |
|:ssl-client-cert |java.security.cert.X509Certificate| | SSL cert if provided |
|:uri |String | Yes | Absolute path, starts with / |
Response Maps
| Key | Type | Required |
| -------- | ------------------------------------------ | -------- |
|:body |ring.core.protocols/StreamableResponseBody| |
|:headers|{String String} or {String [String]} | Yes |
|:status |Integer | Yes |
Response body satisfies StreamableResponseBody protocol:
(defprotocol StreamableResponseBody
(write-body-to-stream [body response output-stream]))
Default implementations: byte[], String, clojure.lang.ISeq, java.io.InputStream, java.io.File, nil
WebSockets
WebSocket response (returned from handler):
(fn [request]
#:ring.websocket{:listener websocket-listener
:protocol "optional-subprotocol"})
Or from async handler:
(fn [request respond raise]
(respond #:ring.websocket{:listener websocket-listener}))
WebSocket Listener Protocol
(defprotocol Listener
(on-open [listener socket])
(on-message [listener socket message]) ; message: CharSequence or ByteBuffer
(on-pong [listener socket data]) ; data: ByteBuffer
(on-error [listener socket throwable])
(on-close [listener socket code reason])) ; code: int, reason: String
Optional ping handler:
(defprotocol PingListener
(on-ping [listener socket data])) ; If not implemented, adapter auto-responds to pings
WebSocket Socket Protocol
(defprotocol Socket
(-open? [socket]) ; Returns truthy if connected
(-send [socket message]) ; message: CharSequence or ByteBuffer
(-ping [socket data]) ; data: ByteBuffer
(-pong [socket data]) ; data: ByteBuffer (unsolicited)
(-close [socket code reason])) ; code: int, reason: String
Optional async send:
(defprotocol AsyncSocket
(-send-async [socket message succeed fail])) ; succeed: (fn []), fail: (fn [throwable])
Scan to join WeChat group