Liking cljdoc? Tell your friends :D

Clojure.spec Coercion

The clojure.spec library specifies the structure of data, validates or destructures it, and can generate data based on the spec.

Warning

clojure.spec by itself doesn't support coercion. reitit uses spec-tools that adds coercion to spec. Like clojure.spec, it's alpha as it leans both on spec walking and clojure.spec.alpha/conform, which is concidered a spec internal, that might be changed or removed later.

Usage

For simple specs (core predicates, spec-tools.core/spec, s/and, s/or, s/coll-of, s/keys, s/map-of, s/nillable and s/every), the transformation is inferred using spec-walker and is automatic. To support all specs (like regex-specs), specs need to be wrapped into Spec Records.

There are CLJ-2116 and CLJ-2251 that would help solve this elegantly. Go vote 'em up.

Example

(require '[reitit.coercion.spec])
(require '[reitit.coercion :as coercion])
(require '[spec-tools.spec :as spec])
(require '[clojure.spec.alpha :as s])
(require '[reitit.core :as r])

;; simple specs, inferred
(s/def ::company string?)
(s/def ::user-id int?)
(s/def ::path-params (s/keys :req-un [::company ::user-id]))

(def router
  (r/router
    ["/:company/users/:user-id" {:name ::user-view
                                 :coercion reitit.coercion.spec/coercion
                                 :parameters {:path ::path-params}}]
    {:compile coercion/compile-request-coercers}))

(defn match-by-path-and-coerce! [path]
  (if-let [match (r/match-by-path router path)]
    (assoc match :parameters (coercion/coerce! match))))

Successful coercion:

(match-by-path-and-coerce! "/metosin/users/123")
; #Match{:template "/:company/users/:user-id",
;        :data {:name :user/user-view,
;               :coercion <<:spec>>
;               :parameters {:path ::path-params}},
;        :result {:path #object[reitit.coercion$request_coercer$]},
;        :path-params {:company "metosin", :user-id "123"},
;        :parameters {:path {:company "metosin", :user-id 123}}
;        :path "/metosin/users/123"}

Failing coercion:

(match-by-path-and-coerce! "/metosin/users/ikitommi")
; => ExceptionInfo Request coercion failed...

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
+kJump to recent docs
Move to previous article
Move to next article
+/Jump to the search field
× close