Merge pull request #452 from TimoKramer/support-operationid

Support operationId in reitit-swagger
This commit is contained in:
Tommi Reiman 2023-01-09 17:29:49 +02:00 committed by GitHub
commit 8087522b82
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 36 deletions

View file

@ -23,6 +23,7 @@ The following route data keys contribute to the generated swagger specification:
| :tags | optional set of string or keyword tags for an endpoint api docs | :tags | optional set of string or keyword tags for an endpoint api docs
| :summary | optional short string summary of an endpoint | :summary | optional short string summary of an endpoint
| :description | optional long description of an endpoint. Supports http://spec.commonmark.org/ | :description | optional long description of an endpoint. Supports http://spec.commonmark.org/
| :operationId | optional string specifying the unique ID of an Operation
Coercion keys also contribute to the docs: Coercion keys also contribute to the docs:

View file

@ -13,9 +13,10 @@
(s/def ::operationId string?) (s/def ::operationId string?)
(s/def ::summary string?) (s/def ::summary string?)
(s/def ::description string?) (s/def ::description string?)
(s/def ::operationId string?)
(s/def ::swagger (s/keys :opt-un [::id])) (s/def ::swagger (s/keys :opt-un [::id]))
(s/def ::spec (s/keys :opt-un [::swagger ::no-doc ::tags ::operationId ::summary ::description])) (s/def ::spec (s/keys :opt-un [::swagger ::no-doc ::tags ::summary ::description ::operationId]))
(def swagger-feature (def swagger-feature
"Feature for handling swagger-documentation for routes. "Feature for handling swagger-documentation for routes.
@ -77,7 +78,7 @@
(let [{:keys [id] :or {id ::default} :as swagger} (-> match :result request-method :data :swagger) (let [{:keys [id] :or {id ::default} :as swagger} (-> match :result request-method :data :swagger)
ids (trie/into-set id) ids (trie/into-set id)
strip-top-level-keys #(dissoc % :id :info :host :basePath :definitions :securityDefinitions) strip-top-level-keys #(dissoc % :id :info :host :basePath :definitions :securityDefinitions)
strip-endpoint-keys #(dissoc % :id :operationId :parameters :responses :summary :description) strip-endpoint-keys #(dissoc % :id :parameters :responses :summary :description :operationId)
swagger (->> (strip-endpoint-keys swagger) swagger (->> (strip-endpoint-keys swagger)
(merge {:swagger "2.0" (merge {:swagger "2.0"
:x-id ids})) :x-id ids}))
@ -90,13 +91,13 @@
(if (and data (not no-doc)) (if (and data (not no-doc))
[method [method
(meta-merge (meta-merge
base-swagger-spec base-swagger-spec
(apply meta-merge (keep (comp :swagger :data) middleware)) (apply meta-merge (keep (comp :swagger :data) middleware))
(apply meta-merge (keep (comp :swagger :data) interceptors)) (apply meta-merge (keep (comp :swagger :data) interceptors))
(if coercion (if coercion
(coercion/get-apidocs coercion :swagger data)) (coercion/get-apidocs coercion :swagger data))
(select-keys data [:tags :operationId :summary :description]) (select-keys data [:tags :summary :description :operationId])
(strip-top-level-keys swagger))])) (strip-top-level-keys swagger))]))
transform-path (fn [[p _ c]] transform-path (fn [[p _ c]]
(if-let [endpoint (some->> c (keep transform-endpoint) (seq) (into {}))] (if-let [endpoint (some->> c (keep transform-endpoint) (seq) (into {}))]
[(swagger-path p (r/options router)) endpoint])) [(swagger-path p (r/options router)) endpoint]))

View file

@ -22,33 +22,35 @@
:swagger {:info {:title "my-api"}} :swagger {:info {:title "my-api"}}
:handler (swagger/create-swagger-handler)}}] :handler (swagger/create-swagger-handler)}}]
["/spec" {:coercion spec/coercion} ["/spec" {:coercion spec/coercion}
["/plus/:z" ["/plus/:z"
{:patch {:summary "patch" {:patch {:summary "patch"
:handler (constantly {:status 200})} :operationId "Patch"
:options {:summary "options"
:middleware [{:data {:swagger {:responses {200 {:description "200"}}}}}]
:handler (constantly {:status 200})} :handler (constantly {:status 200})}
:get {:summary "plus" :options {:summary "options"
:parameters {:query {:x int?, :y int?} :middleware [{:data {:swagger {:responses {200 {:description "200"}}}}}]
:path {:z int?}} :handler (constantly {:status 200})}
:swagger {:responses {400 {:schema {:type "string"} :get {:summary "plus"
:description "kosh"}}} :operationId "GetPlus"
:responses {200 {:body {:total int?}} :parameters {:query {:x int?, :y int?}
500 {:description "fail"}} :path {:z int?}}
:handler (fn [{{{:keys [x y]} :query :swagger {:responses {400 {:schema {:type "string"}
{:keys [z]} :path} :parameters}] :description "kosh"}}}
{:status 200, :body {:total (+ x y z)}})} :responses {200 {:body {:total int?}}
:post {:summary "plus with body" 500 {:description "fail"}}
:parameters {:body (ds/maybe [int?]) :handler (fn [{{{:keys [x y]} :query
:path {:z int?}} {:keys [z]} :path} :parameters}]
:swagger {:responses {400 {:schema {:type "string"} {:status 200, :body {:total (+ x y z)}})}
:description "kosh"}}} :post {:summary "plus with body"
:responses {200 {:body {:total int?}} :parameters {:body (ds/maybe [int?])
500 {:description "fail"}} :path {:z int?}}
:handler (fn [{{{:keys [z]} :path :swagger {:responses {400 {:schema {:type "string"}
xs :body} :parameters}] :description "kosh"}}}
{:status 200, :body {:total (+ (reduce + xs) z)}})}}]] :responses {200 {:body {:total int?}}
500 {:description "fail"}}
:handler (fn [{{{:keys [z]} :path
xs :body} :parameters}]
{:status 200, :body {:total (+ (reduce + xs) z)}})}}]]
["/malli" {:coercion malli/coercion} ["/malli" {:coercion malli/coercion}
["/plus/*z" ["/plus/*z"
@ -118,6 +120,7 @@
(app {:request-method :get (app {:request-method :get
:uri "/api/schema/plus/3" :uri "/api/schema/plus/3"
:query-params {:x "2", :y "1"}}))))) :query-params {:x "2", :y "1"}})))))
(testing "swagger-spec" (testing "swagger-spec"
(let [spec (:body (app {:request-method :get (let [spec (:body (app {:request-method :get
:uri "/api/swagger.json"})) :uri "/api/swagger.json"}))
@ -126,6 +129,7 @@
:info {:title "my-api"} :info {:title "my-api"}
:paths {"/api/spec/plus/{z}" {:patch {:parameters [] :paths {"/api/spec/plus/{z}" {:patch {:parameters []
:summary "patch" :summary "patch"
:operationId "Patch"
:responses {:default {:description ""}}} :responses {:default {:description ""}}}
:options {:parameters [] :options {:parameters []
:summary "options" :summary "options"
@ -156,7 +160,8 @@
400 {:schema {:type "string"} 400 {:schema {:type "string"}
:description "kosh"} :description "kosh"}
500 {:description "fail"}} 500 {:description "fail"}}
:summary "plus"} :summary "plus"
:operationId "GetPlus"}
:post {:parameters [{:in "body", :post {:parameters [{:in "body",
:name "body", :name "body",
:description "", :description "",