ring-middleware-accept is a Ring middleware component for performing server-driven content negotiation.
It allows Ring handlers to select the most appropriate content to output based on the value of these headers in the incoming request:
It implements RFC 2616 sections 14.1–4, including wildcard and prefix matching rules, client-side q-values, and server-side source quality (qs) values.
ring-middleware-accept is available in Clojars. Add it as a dependency in your Leiningen project's project.clj:
[ring-middleware-accept "2.0.3"]
or to your Maven project's pom.xml:
<dependency>
<groupId>ring-middleware-accept</groupId>
<artifactId>ring-middleware-accept</artifactId>
<version>2.0.3</version>
</dependency>
ring-middleware-accept exposes a single public function, wrap-accept, in the namespace ring.middleware.accept. This function takes two arguments: the handler to be wrapped, and a map of the content types offered by the handler.
For example:
(wrap-accept my-handler
{:mime ["text/html" "text/plain"], :language ["en" "fr" "de"]})
Valid keys in the map are :mime (corresponding to the Accept header), :language, :charset, and :encoding. In the simplest case, as in the example above, the map values are just vectors of strings.
The wrapper augments the request-map which is passed to the handler with an :accept entry. Its value is a map of results, i.e. which of the offered content types the client should be served.
For example:
{:mime "text/html", :language "en"}
If the client cannot accept any of the offered types, some of the map entries will be nil. This may warrant a 406 Not Acceptable HTTP response.
(ns example.web
(:require [ring.middleware.accept :refer [wrap-accept]])
;...
)
(defroutes routes
(GET "/greeting" {accept :accept}
(case (:language accept)
"en" "hello"
"fr" "bonjour"
"de" "hallo")))
(def app
(-> routes
(wrap-accept {:language ["en" "fr" "de"]})
))
Content types can be given aliases using the :as keyword.
{:language ["en-gb" :as :british, "en-us" :as :american]
:mime ["application/json" :as :json, "text/html" :as :html]}
These aliases will then used in the map of results:
{:language :british, :mime :html}
The :qs keyword can be used to assign quality values to the content types which the server is offering. These are the server-side equivalent of the q-values found in client requests.
This example shows a server expressing a preference for HTML over plain text in the ratio 2:1.
{:mime ["text/html" :qs 1, "text/plain" :qs 0.5]}
These values are used to determine which content type is chosen in the event of the client being able to accept more than one of those on offer. ring-middleware-accept follows the de facto standard of multiplying client q-values and server qs-values, and selecting the greatest product.
This means that in our example, a client which accepts text/plain,text/html will be served HTML, but a client which accepts text/plain;q=1,text/html;q=0.1 will be served plain text. This is because the text/plain product 1×0.5 is greater than the text/html product 0.1×1.
Copyright © 2014 rufoa
Distributed under the Eclipse Public License, the same as Clojure.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |