Skip to content

Validation and coercion

Tommi Reiman edited this page Jan 31, 2017 · 6 revisions

Changed in 1.2.0

Input and output schemas are by default coerced automatically using a schema coercion matcher based on the parameter type and request/response format. Ring-swagger is used as a coercion backend. Coercion can be customized either api, context or endpoint -level.

  • coercion is a function of request => coercion-type => schema-matcher
  • if coercion fails, an typed Exception is thrown and caught by a default middleware and turned into a http response
  • coercion can be set at api, context or endpoint-level via the :coercion option.
  • coercion helpers are in compojure.api.middleware:
    • string-coercion-matcher (from string -> Clojure)
    • json-coercion-matcher (from JSON -> Clojure)
    • create-coercion & default-coercion-options to easily configure stuff
  • user negotiated format information by Muuntaja is provided at runtime to determine the request/response body format
  • the following default coercions are applied:
Format Request Response
application/edn validate validate
application/transit+json validate validate
application/transit+msgpack validate validate
application/json json-coercion-matcher validate
application/msgpack json-coercion-matcher validate
application/x-yaml json-coercion-matcher validate

Defaults as code:

(def default-coercion-options
  {:body {:default (constantly nil)
          :formats {"application/json" json-coercion-matcher
                    "application/msgpack" json-coercion-matcher
                    "application/x-yaml" json-coercion-matcher}}
   :string string-coercion-matcher
   :response {:default (constantly nil)
              :formats {}}})

Examples of coercion:

(require '[compojure.api.middleware :as mw])

;; create (with defaults)
(mw/create-coercion)
(mw/create-coercion mw/default-coercion-options)

;; no response coercion
(mw/create-coercion (dissoc mw/default-coercion-options :response)

;; disable all coercion
nil
(mw/create-coercion nil)

Example usage

(def no-response-coercion
  (mw/create-coercion (dissoc mw/default-coercion-options :response))

;; at api level
(api
  {:coercion no-response-coercion}
  ...)

;; at context level
(api
  (context "/coercion" []
    :coercion no-response-coercion
    ...))

;; at endpoints
(api
  (GET "/coercion" []
    :coercion no-response-coercion
    ...))

Examples

  • See the tests
  • Example of turning off the default coercion but leaving all schema validations in place:
(compojure.api.sweet/api
  {:coercion (fn validation-only [_request]
                (fn [_coercion-type]
                  (fn [_schema]
                    nil)))
  ,,,}
  ,,,)