Skip to content

Validation and coercion

Tommi Reiman edited this page Aug 3, 2016 · 6 revisions

TODO: rewrite

Input and output schemas are by default coerced automatically using a schema coercion matcher linked to a certail coercion type. There are three types of coercion and currently two different coercion matchers available (from Ring-Swagger).

type default coercion matcher used with
:body json-schema-coercion-matcher request body
:string query-schema-coercion-matcher query, path, header and form parameters
:response json-schema-coercion-matcher response body

One can override the default coercion behavior by providing a coercion function of type ring-request->coercion-type->coercion-matcher either by:

  1. api-middleware option :coercion
  2. route-level restructuring :coercion

As the coercion function takes in the ring-request, one can select a coercion matcher based on the user-selected wire format or any other header. The plan is to provide extendable protocol-based coercion out-of-the-box (Transit doesn't need any coercion, XML requires some extra love with sequences). Stay tuned.

Examples of overriding the default coercion can found in the the tests.

All coercion code uses ring.swagger.schema/coerce! internally, which throws managed exceptions when a value can't be coerced. The api-middleware catches these exceptions and returns the validation error as a serializable Clojure data structure, sent to the client.

One can also call ring.swagger.schema/coerce! manually:

(require '[ring.swagger.schema :refer [coerce!])
(require '[schema.core :as s])

(s/defschema Thingie {:id Long
                      :tag (s/enum :kikka :kukka)})

(coerce! Thingie {:id 123, :tag "kikka"})
; => {:id 123 :tag :kikka}

(coerce! Thingie {:id 123, :tags "kakka"})
; => ExceptionInfo throw+: {:type :ring.swagger.schema/validation, :error {:tags disallowed-key, :tag missing-required-key}}  ring.swagger.schema/coerce! (schema.clj:88)
Clone this wiki locally