mirror of
https://github.com/metosin/reitit.git
synced 2025-12-16 16:01:11 +00:00
Compare commits
13 commits
211e434fcf
...
a81972eb70
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a81972eb70 | ||
|
|
c3a152a44e | ||
|
|
c0bc789863 | ||
|
|
78aba57d2d | ||
|
|
451b286f1d | ||
|
|
eb06404f1e | ||
|
|
af7313bd9b | ||
|
|
ea58100fec | ||
|
|
a4576cc622 | ||
|
|
9d88d92241 | ||
|
|
d16aac673e | ||
|
|
dede2db213 | ||
|
|
f1ade4b089 |
7 changed files with 101 additions and 4 deletions
|
|
@ -16,6 +16,7 @@ We use [Break Versioning][breakver]. The version numbers follow a `<major>.<mino
|
|||
|
||||
* Improve & document how response schemas get picked in per-content-type coercion. See [docs](./doc/ring/coercion.md#per-content-type-coercion). [#745](https://github.com/metosin/reitit/issues/745).
|
||||
* **BREAKING** Remove unused `reitit.dependency` ns. [#763](https://github.com/metosin/reitit/pull/763)
|
||||
* Support passing options to malli humanize. See [docs](./doc/coercion/malli_coercion.md). [#467](https://github.com/metosin/reitit/issues/467)
|
||||
|
||||
## 0.9.2 (2025-10-28)
|
||||
|
||||
|
|
|
|||
|
|
@ -96,3 +96,29 @@ Using `create` with options to create the coercion instead of `coercion`:
|
|||
;; malli options
|
||||
:options nil})
|
||||
```
|
||||
|
||||
## Configuring humanize error messages
|
||||
|
||||
Malli humanized error messages can be configured using `:options :errors`:
|
||||
|
||||
```clj
|
||||
(reitit.coercion.malli/create
|
||||
{:options
|
||||
{:errors (assoc malli.error/default-errors
|
||||
:malli.core/missing-key {:error/message {:en "MISSING"}})}})
|
||||
```
|
||||
|
||||
See the malli docs for more info.
|
||||
|
||||
## Custom registry
|
||||
|
||||
Malli registry can be configured conveniently via `:options :registry`:
|
||||
|
||||
```clj
|
||||
(require '[malli.core :as m])
|
||||
|
||||
(reitit.coercion.malli/create
|
||||
{:options
|
||||
{:registry {:registry (merge (m/default-schemas)
|
||||
{:my-type :string})}}})
|
||||
```
|
||||
|
|
|
|||
|
|
@ -188,7 +188,8 @@
|
|||
(-open-model [_ schema] schema)
|
||||
(-encode-error [_ error]
|
||||
(cond-> error
|
||||
(show? :humanized) (assoc :humanized (me/humanize error {:wrap :message}))
|
||||
(show? :humanized) (assoc :humanized (me/humanize error (cond-> {:wrap :message}
|
||||
options (merge options))))
|
||||
(show? :schema) (update :schema edn/write-string opts)
|
||||
(show? :errors) (-> (me/with-error-messages opts)
|
||||
(update :errors (partial map #(update % :schema edn/write-string opts))))
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@
|
|||
(= (count model) 1) (first model)
|
||||
;; here be dragons, best effort
|
||||
(every? map? model) (apply mm/meta-merge model)
|
||||
;; all elements are the same
|
||||
(apply = model) (first model)
|
||||
;; fail fast
|
||||
:else (ex/fail! ::model-error {:message "Can't merge nested clojure specs", :spec model}))
|
||||
name))
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
[metosin/reitit-sieppari "0.9.2"]
|
||||
[metosin/reitit-pedestal "0.9.2"]
|
||||
[metosin/ring-swagger-ui "5.20.0"]
|
||||
[metosin/spec-tools "0.10.7"]
|
||||
[metosin/spec-tools "0.10.8"]
|
||||
[metosin/schema-tools "0.13.1"]
|
||||
[metosin/muuntaja "0.6.11"]
|
||||
[metosin/jsonista "0.3.13"]
|
||||
|
|
@ -95,7 +95,7 @@
|
|||
|
||||
;; modules dependencies
|
||||
[metosin/schema-tools "0.13.1"]
|
||||
[metosin/spec-tools "0.10.7"]
|
||||
[metosin/spec-tools "0.10.8"]
|
||||
[metosin/muuntaja "0.6.11"]
|
||||
[metosin/sieppari "0.0.0-alpha13"]
|
||||
[metosin/jsonista "0.3.13"]
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
[reitit.swagger-ui :as swagger-ui]
|
||||
[schema.core :as s]
|
||||
[schema-tools.core]
|
||||
[clojure.spec.alpha :as sp]
|
||||
[spec-tools.core :as st]
|
||||
[spec-tools.data-spec :as ds]))
|
||||
|
||||
|
|
@ -1027,3 +1028,36 @@
|
|||
"reitit.openapi-test.Y" {:type "integer"}}}}
|
||||
spec))
|
||||
(is (nil? (validate spec))))))
|
||||
|
||||
(sp/def ::address string?)
|
||||
(sp/def ::zip int?)
|
||||
(sp/def ::city string?)
|
||||
(sp/def ::street string?)
|
||||
(sp/def ::or-and-schema (sp/keys :req-un [(or (and ::address ::zip) (and ::city ::street))]))
|
||||
|
||||
(deftest openapi-spec-tests
|
||||
(testing "s/keys + or maps to :anyOf"
|
||||
(let [app (ring/ring-handler
|
||||
(ring/router
|
||||
[["/openapi.json"
|
||||
{:get {:no-doc true
|
||||
:openapi {:info {:title "" :version "0.0.1"}}
|
||||
:handler (openapi/create-openapi-handler)}}]
|
||||
|
||||
["/spec" {:coercion spec/coercion
|
||||
:post {:summary "or-and-schema"
|
||||
:request {:content {"application/json" {:schema ::or-and-schema}}}
|
||||
:handler identity}}]]
|
||||
{:validate reitit.ring.spec/validate
|
||||
:data {:middleware [openapi/openapi-feature]}}))
|
||||
spec (:body (app {:request-method :get :uri "/openapi.json"}))]
|
||||
(is (nil? (validate spec)))
|
||||
(is (= {:title "reitit.openapi-test/or-and-schema"
|
||||
:type "object"
|
||||
:properties {"address" {:type "string"}
|
||||
"zip" {:type "integer" :format "int64"}
|
||||
"city" {:type "string"}
|
||||
"street" {:type "string"}}
|
||||
:anyOf [{:required ["address" "zip"]}
|
||||
{:required ["city" "street"]}]}
|
||||
(get-in spec [:paths "/spec" :post :requestBody :content "application/json" :schema]))))))
|
||||
|
|
|
|||
|
|
@ -583,7 +583,40 @@
|
|||
:request-method :get}))]
|
||||
|
||||
(is (= {:status 200, :body {:total "FOO: this, BAR: that"}} (call m/schema custom-meta-merge-checking-schema)))
|
||||
(is (= {:status 200, :body {:total "FOO: this, BAR: that"}} (call identity custom-meta-merge-checking-parameters)))))))
|
||||
(is (= {:status 200, :body {:total "FOO: this, BAR: that"}} (call identity custom-meta-merge-checking-parameters)))))
|
||||
|
||||
(testing "malli options"
|
||||
(let [->app (fn [options]
|
||||
(ring/ring-handler
|
||||
(ring/router
|
||||
["/api" {:get {:parameters {:body [:map
|
||||
[:i :int]
|
||||
[:x :string]]}
|
||||
:handler (fn [{{:keys [body]} :parameters}]
|
||||
{:status 200 :body body})}}]
|
||||
{:data {:middleware [rrc/coerce-exceptions-middleware
|
||||
rrc/coerce-request-middleware
|
||||
rrc/coerce-response-middleware]
|
||||
:coercion (malli/create options)}})))
|
||||
request {:uri "/api"
|
||||
:request-method :get
|
||||
:muuntaja/request {:format "application/json"}}]
|
||||
(testing "humanize options"
|
||||
(is (= {:i ["should be an integer"] :x ["missing required key"]}
|
||||
(-> ((->app nil) (assoc request :body-params {:i "x"}))
|
||||
:body
|
||||
:humanized)))
|
||||
(is (= {:i ["SHOULD INT"] :x ["MISSING"]}
|
||||
(-> ((->app {:options {:errors {:int {:error/message {:en "SHOULD INT"}}
|
||||
:malli.core/missing-key {:error/message {:en "MISSING"}}}}})
|
||||
(assoc request :body-params {:i "x"}))
|
||||
:body
|
||||
:humanized))))
|
||||
(testing "overriding registry"
|
||||
(is (= {:body {:i "x" :x "x"} :status 200}
|
||||
(-> ((->app {:options {:registry (merge (m/default-schemas)
|
||||
{:int :string})}})
|
||||
(assoc request :body-params {:i "x" :x "x"}))))))))))
|
||||
|
||||
#?(:clj
|
||||
(deftest per-content-type-test
|
||||
|
|
|
|||
Loading…
Reference in a new issue