-
Notifications
You must be signed in to change notification settings - Fork 150
Validation and coercion
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:
- api-middleware option
:coercion
- 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)