mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 08:21:11 +00:00
Merge pull request #676 from metosin/update-validator
update openapi-schema-validator, fix openapi requestBody description
This commit is contained in:
commit
15790f3028
4 changed files with 74 additions and 51 deletions
|
|
@ -125,8 +125,9 @@
|
||||||
(when request
|
(when request
|
||||||
;; request allow to different :requestBody per content-type
|
;; request allow to different :requestBody per content-type
|
||||||
{:requestBody
|
{:requestBody
|
||||||
{:content (merge
|
(merge
|
||||||
(select-keys request [:description])
|
(select-keys request [:description])
|
||||||
|
{:content (merge
|
||||||
(when-let [{:keys [schema] :as data} (coercion/get-default request)]
|
(when-let [{:keys [schema] :as data} (coercion/get-default request)]
|
||||||
(into {}
|
(into {}
|
||||||
(map (fn [content-type]
|
(map (fn [content-type]
|
||||||
|
|
@ -141,7 +142,7 @@
|
||||||
:type :schema
|
:type :schema
|
||||||
:content-type content-type})]
|
:content-type content-type})]
|
||||||
[content-type (->content data schema)])))
|
[content-type (->content data schema)])))
|
||||||
(dissoc (:content request) :default)))}})
|
(dissoc (:content request) :default)))})})
|
||||||
(when multipart
|
(when multipart
|
||||||
{:requestBody
|
{:requestBody
|
||||||
{:content
|
{:content
|
||||||
|
|
|
||||||
23
package-lock.json
generated
23
package-lock.json
generated
|
|
@ -6,7 +6,7 @@
|
||||||
"": {
|
"": {
|
||||||
"name": "reitit",
|
"name": "reitit",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@seriousme/openapi-schema-validator": "^2.1.0",
|
"@seriousme/openapi-schema-validator": "^2.2.1",
|
||||||
"karma": "^4.1.0",
|
"karma": "^4.1.0",
|
||||||
"karma-chrome-launcher": "^2.2.0",
|
"karma-chrome-launcher": "^2.2.0",
|
||||||
"karma-cli": "^2.0.0",
|
"karma-cli": "^2.0.0",
|
||||||
|
|
@ -15,20 +15,31 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@seriousme/openapi-schema-validator": {
|
"node_modules/@seriousme/openapi-schema-validator": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@seriousme/openapi-schema-validator/-/openapi-schema-validator-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@seriousme/openapi-schema-validator/-/openapi-schema-validator-2.2.1.tgz",
|
||||||
"integrity": "sha512-J461zq7Qj4N/SQlUiyXFelGqtKJenW9DnTjX5fraLk9Lmybq7B6goBieAlMf3D2W+grrVz/hSDodB0faoD9y2Q==",
|
"integrity": "sha512-I+6l2vZ4qx+RyUo8GNnIbeqbv5ao1enSdNFPJ7x3slIVLU8aSBf228qpo+6iNWbRMK4ktF91jsv5KN7PpaJQtg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^8.11.0",
|
"ajv": "^8.12.0",
|
||||||
"ajv-draft-04": "^1.0.0",
|
"ajv-draft-04": "^1.0.0",
|
||||||
"ajv-formats": "^2.1.1",
|
"ajv-formats": "^2.1.1",
|
||||||
"js-yaml": "^4.1.0"
|
"js-yaml": "^4.1.0",
|
||||||
|
"minimist": "^1.2.8"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
"bundle-api": "bin/bundle-api-cli.js",
|
||||||
"validate-api": "bin/validate-api-cli.js"
|
"validate-api": "bin/validate-api-cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@seriousme/openapi-schema-validator/node_modules/minimist": {
|
||||||
|
"version": "1.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||||
|
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "1.3.7",
|
"version": "1.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "reitit",
|
"name": "reitit",
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@seriousme/openapi-schema-validator": "^2.1.0",
|
"@seriousme/openapi-schema-validator": "^2.2.1",
|
||||||
"karma": "^4.1.0",
|
"karma": "^4.1.0",
|
||||||
"karma-chrome-launcher": "^2.2.0",
|
"karma-chrome-launcher": "^2.2.0",
|
||||||
"karma-cli": "^2.0.0",
|
"karma-cli": "^2.0.0",
|
||||||
|
|
|
||||||
|
|
@ -869,19 +869,20 @@
|
||||||
(ring/router
|
(ring/router
|
||||||
[["/openapi.json"
|
[["/openapi.json"
|
||||||
{:get {:no-doc true
|
{:get {:no-doc true
|
||||||
|
:openapi {:info {:title "" :version "0.0.1"}}
|
||||||
:handler (openapi/create-openapi-handler)}}]
|
:handler (openapi/create-openapi-handler)}}]
|
||||||
|
|
||||||
["/malli" {:coercion malli/coercion}
|
["/malli" {:coercion malli/coercion}
|
||||||
["/plus" {:post {:summary "plus with body"
|
["/plus" {:post {:summary "plus with body"
|
||||||
:request {:description "body description"
|
:request {:description "body description"
|
||||||
:content {"application/json" {:schema {:x int?, :y int?}
|
:content {"application/json" {:schema {:x int?, :y int?}
|
||||||
:examples {"1+1" {:x 1, :y 1}
|
:examples {"1+1" {:value {:x 1, :y 1}}
|
||||||
"1+2" {:x 1, :y 2}}
|
"1+2" {:value {:x 1, :y 2}}}
|
||||||
:openapi {:example {:x 2, :y 2}}}}}
|
:openapi {:example {:x 2, :y 2}}}}}
|
||||||
:responses {200 {:description "success"
|
:responses {200 {:description "success"
|
||||||
:content {"application/json" {:schema {:total int?}
|
:content {"application/json" {:schema {:total int?}
|
||||||
:examples {"2" {:total 2}
|
:examples {"2" {:value {:total 2}}
|
||||||
"3" {:total 3}}
|
"3" {:value {:total 3}}}
|
||||||
:openapi {:example {:total 4}}}}}}
|
:openapi {:example {:total 4}}}}}}
|
||||||
:handler (fn [request]
|
:handler (fn [request]
|
||||||
(let [{:keys [x y]} (-> request :parameters :body)]
|
(let [{:keys [x y]} (-> request :parameters :body)]
|
||||||
|
|
@ -891,49 +892,51 @@
|
||||||
:data {:middleware [openapi/openapi-feature
|
:data {:middleware [openapi/openapi-feature
|
||||||
rrc/coerce-exceptions-middleware
|
rrc/coerce-exceptions-middleware
|
||||||
rrc/coerce-request-middleware
|
rrc/coerce-request-middleware
|
||||||
rrc/coerce-response-middleware]}}))]
|
rrc/coerce-response-middleware]}}))
|
||||||
(is (= {"/malli/plus" {:post {:requestBody {:content {:description "body description",
|
spec (:body (app {:request-method :get :uri "/openapi.json"}))]
|
||||||
"application/json" {:schema {:type "object",
|
(is (= {"/malli/plus" {:post {:requestBody {:description "body description",
|
||||||
|
:content {"application/json" {:schema {:type "object",
|
||||||
:properties {:x {:type "integer"},
|
:properties {:x {:type "integer"},
|
||||||
:y {:type "integer"}},
|
:y {:type "integer"}},
|
||||||
:required [:x :y],
|
:required [:x :y],
|
||||||
:additionalProperties false},
|
:additionalProperties false},
|
||||||
:examples {"1+1" {:x 1, :y 1}, "1+2" {:x 1, :y 2}},
|
:examples {"1+1" {:value {:x 1, :y 1}}
|
||||||
|
"1+2" {:value {:x 1, :y 2}}},
|
||||||
:example {:x 2, :y 2}}}},
|
:example {:x 2, :y 2}}}},
|
||||||
:responses {200 {:description "success",
|
:responses {200 {:description "success",
|
||||||
:content {"application/json" {:schema {:type "object",
|
:content {"application/json" {:schema {:type "object",
|
||||||
:properties {:total {:type "integer"}},
|
:properties {:total {:type "integer"}},
|
||||||
:required [:total],
|
:required [:total],
|
||||||
:additionalProperties false},
|
:additionalProperties false},
|
||||||
:examples {"2" {:total 2}, "3" {:total 3}},
|
:examples {"2" {:value {:total 2}},
|
||||||
|
"3" {:value {:total 3}}},
|
||||||
:example {:total 4}}}}},
|
:example {:total 4}}}}},
|
||||||
:summary "plus with body"}}}
|
:summary "plus with body"}}}
|
||||||
(-> {:request-method :get
|
(:paths spec)))
|
||||||
:uri "/openapi.json"}
|
(is (nil? (validate spec))))
|
||||||
(app)
|
|
||||||
:body
|
|
||||||
:paths))))
|
|
||||||
(testing "ref schemas"
|
(testing "ref schemas"
|
||||||
(let [registry (merge (mc/base-schemas)
|
(let [registry (merge (mc/base-schemas)
|
||||||
(mc/type-schemas)
|
(mc/type-schemas)
|
||||||
{::plus [:map [:x :int] [:y ::y]]
|
{"plus" [:map [:x :int] [:y "y"]]
|
||||||
::y :int})
|
"y" :int})
|
||||||
app (ring/ring-handler
|
app (ring/ring-handler
|
||||||
(ring/router
|
(ring/router
|
||||||
[["/openapi.json"
|
[["/openapi.json"
|
||||||
{:get {:no-doc true
|
{:get {:no-doc true
|
||||||
|
:openapi {:info {:title "" :version "0.0.1"}}
|
||||||
:handler (openapi/create-openapi-handler)}}]
|
:handler (openapi/create-openapi-handler)}}]
|
||||||
["/post"
|
["/post"
|
||||||
{:post {:coercion malli/coercion
|
{:post {:coercion malli/coercion
|
||||||
:parameters {:body (mc/schema ::plus {:registry registry})}
|
:parameters {:body (mc/schema "plus" {:registry registry})}
|
||||||
:handler identity}}]
|
:handler identity}}]
|
||||||
["/get"
|
["/get"
|
||||||
{:get {:coercion malli/coercion
|
{:get {:coercion malli/coercion
|
||||||
:parameters {:query (mc/schema ::plus {:registry registry})}
|
:parameters {:query (mc/schema "plus" {:registry registry})}
|
||||||
:handler identity}}]]))
|
:handler identity}}]]))
|
||||||
spec (:body (app {:request-method :get :uri "/openapi.json"}))]
|
spec (:body (app {:request-method :get :uri "/openapi.json"}))]
|
||||||
(is (= {:openapi "3.1.0"
|
(is (= {:openapi "3.1.0"
|
||||||
:x-id #{:reitit.openapi/default}
|
:x-id #{:reitit.openapi/default}
|
||||||
|
:info {:title "" :version "0.0.1"}
|
||||||
:paths {"/get" {:get {:parameters [{:in "query"
|
:paths {"/get" {:get {:parameters [{:in "query"
|
||||||
:name :x
|
:name :x
|
||||||
:required true
|
:required true
|
||||||
|
|
@ -941,25 +944,27 @@
|
||||||
{:in "query"
|
{:in "query"
|
||||||
:name :y
|
:name :y
|
||||||
:required true
|
:required true
|
||||||
:schema {:$ref "#/components/schemas/reitit.openapi-test~1y"}}]}}
|
:schema {:$ref "#/components/schemas/y"}}]}}
|
||||||
"/post" {:post
|
"/post" {:post
|
||||||
{:requestBody
|
{:requestBody
|
||||||
{:content
|
{:content
|
||||||
{"application/json"
|
{"application/json"
|
||||||
{:schema
|
{:schema
|
||||||
{:$ref "#/components/schemas/reitit.openapi-test~1plus"}}}}}}}
|
{:$ref "#/components/schemas/plus"}}}}}}}
|
||||||
:components {:schemas
|
:components {:schemas
|
||||||
{"reitit.openapi-test/y" {:type "integer"}
|
{"y" {:type "integer"}
|
||||||
"reitit.openapi-test/plus" {:type "object"
|
"plus" {:type "object"
|
||||||
:properties {:x {:type "integer"}
|
:properties {:x {:type "integer"}
|
||||||
:y {:$ref "#/components/schemas/reitit.openapi-test~1y"}}
|
:y {:$ref "#/components/schemas/y"}}
|
||||||
:required [:x :y]}}}}
|
:required [:x :y]}}}}
|
||||||
spec))))
|
spec))
|
||||||
|
(is (nil? (validate spec)))))
|
||||||
(testing "var schemas"
|
(testing "var schemas"
|
||||||
(let [app (ring/ring-handler
|
(let [app (ring/ring-handler
|
||||||
(ring/router
|
(ring/router
|
||||||
[["/openapi.json"
|
[["/openapi.json"
|
||||||
{:get {:no-doc true
|
{:get {:no-doc true
|
||||||
|
:openapi {:info {:title "" :version "0.0.1"}}
|
||||||
:handler (openapi/create-openapi-handler)}}]
|
:handler (openapi/create-openapi-handler)}}]
|
||||||
["/post"
|
["/post"
|
||||||
{:post {:coercion malli/coercion
|
{:post {:coercion malli/coercion
|
||||||
|
|
@ -972,6 +977,7 @@
|
||||||
spec (:body (app {:request-method :get :uri "/openapi.json"}))]
|
spec (:body (app {:request-method :get :uri "/openapi.json"}))]
|
||||||
(is (= {:openapi "3.1.0"
|
(is (= {:openapi "3.1.0"
|
||||||
:x-id #{:reitit.openapi/default}
|
:x-id #{:reitit.openapi/default}
|
||||||
|
:info {:title "" :version "0.0.1"}
|
||||||
:paths
|
:paths
|
||||||
{"/post"
|
{"/post"
|
||||||
{:post
|
{:post
|
||||||
|
|
@ -999,4 +1005,9 @@
|
||||||
:y {:$ref "#/components/schemas/reitit.openapi-test~1Y"}}
|
:y {:$ref "#/components/schemas/reitit.openapi-test~1Y"}}
|
||||||
:required [:x :y]}
|
:required [:x :y]}
|
||||||
"reitit.openapi-test/Y" {:type "integer"}}}}
|
"reitit.openapi-test/Y" {:type "integer"}}}}
|
||||||
spec)))))
|
spec))
|
||||||
|
;; TODO: the OAS 3.1 json schema disallows "/" in :components :schemas keys,
|
||||||
|
;; even though the text of the spec allows it. See:
|
||||||
|
;; https://github.com/seriousme/openapi-schema-validator/blob/772375bf4895f0e641d103c27140cdd1d2afc34e/schemas/v3.1/schema.json#L282
|
||||||
|
#_
|
||||||
|
(is (nil? (validate spec))))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue