Skip to content
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


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:

  • Accept
  • Accept-Language
  • Accept-Charset
  • Accept-Encoding

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.

Build Status


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:



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.

Simple example

(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}

Source quality (qs) values

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.


Content negotiation middleware for Ring



No releases published


No packages published
You can’t perform that action at this time.