mirror of
https://github.com/metosin/reitit.git
synced 2025-12-18 17:01:11 +00:00
commit
938e6b07b4
11 changed files with 204 additions and 128 deletions
|
|
@ -24,8 +24,8 @@ We use [Break Versioning][breakver]. The version numbers follow a `<major>.<mino
|
|||
```clj
|
||||
[metosin/sieppari "0.0.0-alpha10"] is available but we use "0.0.0-alpha8"
|
||||
[metosin/malli "0.0.1-20200404.091302-14"] is available but we use "0.0.1-20200305.102752-13"
|
||||
[metosin/ring-swagger-ui "3.25.0"] is available but we use "3.24.3"
|
||||
[metosin/spec-tools "0.10.2"] is available but we use "0.10.0"
|
||||
[metosin/ring-swagger-ui "3.25.3"] is available but we use "2.2.10"
|
||||
[metosin/spec-tools "0.10.3"] is available but we use "0.10.0"
|
||||
[metosin/schema-tools "0.12.2"] is available but we use "0.12.1"
|
||||
[metosin/muuntaja "0.6.7"] is available but we use "0.6.6"
|
||||
[metosin/jsonista "0.2.6"] is available but we use "0.2.5"
|
||||
|
|
@ -67,6 +67,10 @@ is called the first time, so that `rfe/push-state` and such can be called
|
|||
|
||||
* lots of bug fixes, see [spec-tools changelog](https://github.com/metosin/spec-tools/blob/master/CHANGELOG.md#0102-2020-05-05)
|
||||
|
||||
### `reitit-malli`
|
||||
|
||||
* Swagger body-parameters don't use empty default, fixes [#399](https://github.com/metosin/reitit/issues/399)
|
||||
|
||||
### `reitit-sieppari`
|
||||
|
||||
* changes from Sieppari:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
[clojure.java.io :as io]
|
||||
[clojure.spec.alpha :as s]
|
||||
[spec-tools.core :as st]
|
||||
[sieppari.async.manifold]
|
||||
[manifold.deferred :as d]))
|
||||
|
||||
(s/def ::x int?)
|
||||
|
|
@ -59,6 +60,7 @@
|
|||
["/download"
|
||||
{:get {:summary "downloads a file"
|
||||
:swagger {:produces ["image/png"]}
|
||||
:responses {200 {:description "image"}}
|
||||
:handler (fn [_]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "image/png"}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
(:require [reitit.http :as http]
|
||||
[reitit.ring :as ring]
|
||||
[reitit.interceptor.sieppari]
|
||||
[sieppari.async.core-async] ;; needed for core.async
|
||||
[sieppari.async.manifold] ;; needed for manifold
|
||||
[ring.adapter.jetty :as jetty]
|
||||
[muuntaja.interceptor]
|
||||
[clojure.core.async :as a]
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
["/download"
|
||||
{:get {:summary "downloads a file"
|
||||
:swagger {:produces ["image/png"]}
|
||||
:responses {200 {:description "image"}}
|
||||
:handler (fn [_]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "image/png"}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
["/download"
|
||||
{:get {:summary "downloads a file"
|
||||
:swagger {:produces ["image/png"]}
|
||||
:responses {200 {:description "image"}}
|
||||
:handler (fn [_]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "image/png"}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
["/download"
|
||||
{:get {:summary "downloads a file"
|
||||
:swagger {:produces ["image/png"]}
|
||||
:responses {200 {:description "image"}}
|
||||
:handler (fn [_]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "image/png"}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
["/download"
|
||||
{:get {:summary "downloads a file"
|
||||
:swagger {:produces ["image/png"]}
|
||||
:responses {200 {:description "image"}}
|
||||
:handler (fn [_]
|
||||
{:status 200
|
||||
:headers {"Content-Type" "image/png"}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@
|
|||
(defmethod extract-parameter :body [_ schema options]
|
||||
(let [swagger-schema (swagger/transform schema (merge options {:in :body, :type :parameter}))]
|
||||
[{:in "body"
|
||||
:name (:title swagger-schema "")
|
||||
:name (:title swagger-schema "body")
|
||||
:description (:description swagger-schema "")
|
||||
:required (not= :maybe (m/name schema))
|
||||
:schema swagger-schema}]))
|
||||
|
|
|
|||
10
project.clj
10
project.clj
|
|
@ -27,12 +27,12 @@
|
|||
[metosin/reitit-frontend "0.4.2"]
|
||||
[metosin/reitit-sieppari "0.4.2"]
|
||||
[metosin/reitit-pedestal "0.4.2"]
|
||||
[metosin/ring-swagger-ui "3.25.0"]
|
||||
[metosin/spec-tools "0.10.2"]
|
||||
[metosin/ring-swagger-ui "3.25.3"]
|
||||
[metosin/spec-tools "0.10.3"]
|
||||
[metosin/schema-tools "0.12.2"]
|
||||
[metosin/muuntaja "0.6.7"]
|
||||
[metosin/jsonista "0.2.6"]
|
||||
[metosin/sieppari "0.0.0-alpha9"]
|
||||
[metosin/sieppari "0.0.0-alpha10"]
|
||||
[metosin/malli "0.0.1-20200404.091302-14"]
|
||||
|
||||
;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
;; modules dependencies
|
||||
[metosin/schema-tools "0.12.2"]
|
||||
[metosin/spec-tools "0.10.2"]
|
||||
[metosin/spec-tools "0.10.3"]
|
||||
[metosin/muuntaja "0.6.7"]
|
||||
[metosin/sieppari]
|
||||
[metosin/jsonista "0.2.6"]
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
[ring "1.8.1"]
|
||||
[ikitommi/immutant-web "3.0.0-alpha1"]
|
||||
[metosin/ring-http-response "0.9.1"]
|
||||
[metosin/ring-swagger-ui "3.25.0"]
|
||||
[metosin/ring-swagger-ui "3.25.3"]
|
||||
|
||||
[criterium "0.4.5"]
|
||||
[org.clojure/test.check "1.0.0"]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
[reitit.interceptor.sieppari :as sieppari]
|
||||
[reitit.http :as http]
|
||||
[reitit.ring :as ring]
|
||||
[reitit.core :as r])
|
||||
[reitit.core :as r]
|
||||
[clojure.core.async :as a])
|
||||
(:import (clojure.lang ExceptionInfo)))
|
||||
|
||||
(defn interceptor [name]
|
||||
|
|
@ -281,6 +282,37 @@
|
|||
(is (= 406 (:status (respond))))
|
||||
(is (= ::nil (raise))))))))))
|
||||
|
||||
(deftest core-async-test
|
||||
(testing "works if registered"
|
||||
(require '[sieppari.async.core-async])
|
||||
(let [response {:status 200, :body "ok"}
|
||||
app (http/ring-handler
|
||||
(http/router
|
||||
["/ping" {:get {:interceptors [{:enter #(a/go %)}]
|
||||
:handler (fn [_] (a/go response))}}])
|
||||
(ring/create-default-handler)
|
||||
{:executor sieppari/executor})]
|
||||
(let [respond (promise)]
|
||||
(app {:request-method :get, :uri "/ping"} respond ::irrelevant)
|
||||
(is (= response (deref respond 100 ::timeout)))))))
|
||||
|
||||
(defrecord MyAsyncContext [])
|
||||
|
||||
(deftest unknown-async-test
|
||||
(testing "works if registered"
|
||||
(let [response {:status 200, :body "ok"}
|
||||
app (http/ring-handler
|
||||
(http/router
|
||||
["/ping" {:get {:interceptors [{:enter map->MyAsyncContext}]
|
||||
:handler (fn [_] response)}}])
|
||||
(ring/create-default-handler)
|
||||
{:executor sieppari/executor})
|
||||
respond (promise)
|
||||
raise (promise)]
|
||||
(app {:request-method :get, :uri "/ping"} respond raise)
|
||||
(let [raised (deref raise 100 ::timeout)]
|
||||
(is (instance? ExceptionInfo raised))))))
|
||||
|
||||
(deftest interceptor-transform-test
|
||||
(let [interceptor (fn [name] {:name name
|
||||
:enter (fn [ctx]
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
[reitit.coercion.schema :as schema]
|
||||
[schema.core :refer [Int]]
|
||||
[muuntaja.core :as m]
|
||||
[spec-tools.data-spec :as ds]))
|
||||
[spec-tools.data-spec :as ds]
|
||||
[schema.core :as s]))
|
||||
|
||||
(def app
|
||||
(ring/ring-handler
|
||||
|
|
@ -79,40 +80,147 @@
|
|||
500 {:description "fail"}}
|
||||
:handler (fn [{{{:keys [x y]} :query
|
||||
{:keys [z]} :path} :parameters}]
|
||||
{:status 200, :body {:total (+ x y z)}})}}]]]
|
||||
{:status 200, :body {:total (+ x y z)}})}
|
||||
:post {:summary "plus with body"
|
||||
:parameters {:body (s/maybe [s/Int])
|
||||
:path {:z s/Int}}
|
||||
:swagger {:responses {400 {:schema {:type "string"}
|
||||
:description "kosh"}}}
|
||||
:responses {200 {:body {:total s/Int}}
|
||||
500 {:description "fail"}}
|
||||
:handler (fn [{{{:keys [z]} :path
|
||||
xs :body} :parameters}]
|
||||
{:status 200, :body {:total (+ (reduce + xs) z)}})}}]]]
|
||||
|
||||
{:data {:middleware [swagger/swagger-feature
|
||||
rrc/coerce-exceptions-middleware
|
||||
rrc/coerce-request-middleware
|
||||
rrc/coerce-response-middleware]}})))
|
||||
|
||||
(require '[fipp.edn])
|
||||
(deftest swagger-test
|
||||
(testing "endpoints work"
|
||||
(testing "spec"
|
||||
(is (= {:body {:total 6}, :status 200}
|
||||
(app
|
||||
{:request-method :get
|
||||
:uri "/api/spec/plus/3"
|
||||
:query-params {:x "2", :y "1"}})))
|
||||
(app {:request-method :get
|
||||
:uri "/api/spec/plus/3"
|
||||
:query-params {:x "2", :y "1"}})))
|
||||
(is (= {:body {:total 7}, :status 200}
|
||||
(app
|
||||
{:request-method :post
|
||||
:uri "/api/spec/plus/3"
|
||||
:body-params [1 3]}))))
|
||||
(app {:request-method :post
|
||||
:uri "/api/spec/plus/3"
|
||||
:body-params [1 3]}))))
|
||||
(testing "schema"
|
||||
(is (= {:body {:total 6}, :status 200}
|
||||
(app
|
||||
{:request-method :get
|
||||
:uri "/api/schema/plus/3"
|
||||
:query-params {:x "2", :y "1"}})))))
|
||||
(app {:request-method :get
|
||||
:uri "/api/schema/plus/3"
|
||||
:query-params {:x "2", :y "1"}})))))
|
||||
(testing "swagger-spec"
|
||||
(let [spec (:body (app
|
||||
{:request-method :get
|
||||
:uri "/api/swagger.json"}))
|
||||
(let [spec (:body (app {:request-method :get
|
||||
:uri "/api/swagger.json"}))
|
||||
expected {:x-id #{::math}
|
||||
:swagger "2.0"
|
||||
:info {:title "my-api"}
|
||||
:paths {"/api/schema/plus/{z}" {:get {:parameters [{:description ""
|
||||
:paths {"/api/spec/plus/{z}" {:get {:parameters [{:in "query"
|
||||
:name "x"
|
||||
:description ""
|
||||
:required true
|
||||
:type "integer"
|
||||
:format "int64"}
|
||||
{:in "query"
|
||||
:name "y"
|
||||
:description ""
|
||||
:required true
|
||||
:type "integer"
|
||||
:format "int64"}
|
||||
{:in "path"
|
||||
:name "z"
|
||||
:description ""
|
||||
:required true
|
||||
:type "integer"
|
||||
:format "int64"}]
|
||||
:responses {200 {:description ""
|
||||
:schema {:type "object"
|
||||
:properties {"total" {:format "int64"
|
||||
:type "integer"}}
|
||||
:required ["total"]}}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus"}
|
||||
:post {:parameters [{:in "body",
|
||||
:name "body",
|
||||
:description "",
|
||||
:required false,
|
||||
:schema {:type "array",
|
||||
:items {:type "integer",
|
||||
:format "int64"}
|
||||
:x-nullable true}}
|
||||
{:in "path"
|
||||
:name "z"
|
||||
:description ""
|
||||
:type "integer"
|
||||
:required true
|
||||
:format "int64"}]
|
||||
:responses {200 {:schema {:properties {"total" {:format "int64"
|
||||
:type "integer"}}
|
||||
:required ["total"]
|
||||
:type "object"}
|
||||
:description ""}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus with body"}}
|
||||
"/api/malli/plus/{z}" {:get {:parameters [{:in "query"
|
||||
:name :x
|
||||
:description ""
|
||||
:required true
|
||||
:type "integer"
|
||||
:format "int64"}
|
||||
{:in "query"
|
||||
:name :y
|
||||
:description ""
|
||||
:required true
|
||||
:type "integer"
|
||||
:format "int64"}
|
||||
{:in "path"
|
||||
:name :z
|
||||
:description ""
|
||||
:required true
|
||||
:type "integer"
|
||||
:format "int64"}]
|
||||
:responses {200 {:schema {:type "object"
|
||||
:properties {:total {:format "int64"
|
||||
:type "integer"}}
|
||||
:required [:total]}
|
||||
:description ""}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus"}
|
||||
:post {:parameters [{:in "body",
|
||||
:name "body",
|
||||
:description "",
|
||||
:required false,
|
||||
:schema {:type "array",
|
||||
:items {:type "integer",
|
||||
:format "int64"}
|
||||
:x-nullable true}}
|
||||
{:in "path"
|
||||
:name :z
|
||||
:description ""
|
||||
:type "integer"
|
||||
:required true
|
||||
:format "int64"}]
|
||||
:responses {200 {:description ""
|
||||
:schema {:properties {:total {:format "int64"
|
||||
:type "integer"}}
|
||||
:required [:total]
|
||||
:type "object"}}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus with body"}}
|
||||
"/api/schema/plus/{z}" {:get {:parameters [{:description ""
|
||||
:format "int32"
|
||||
:in "query"
|
||||
:name "x"
|
||||
|
|
@ -139,107 +247,31 @@
|
|||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus"}}
|
||||
"/api/malli/plus/{z}" {:get {:parameters [{:description ""
|
||||
:format "int64"
|
||||
:in "query"
|
||||
:name :x
|
||||
:required true
|
||||
:type "integer"}
|
||||
{:description ""
|
||||
:format "int64"
|
||||
:in "query"
|
||||
:name :y
|
||||
:required true
|
||||
:type "integer"}
|
||||
{:in "path"
|
||||
:name :z
|
||||
:description ""
|
||||
:type "integer"
|
||||
:required true
|
||||
:format "int64"}]
|
||||
:responses {200 {:description ""
|
||||
:schema {:properties {:total {:format "int64"
|
||||
:type "integer"}}
|
||||
:required [:total]
|
||||
:type "object"}}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus"}
|
||||
:post {:parameters [{:in "body",
|
||||
:name "",
|
||||
:description "",
|
||||
:required false,
|
||||
:schema {:type "array",
|
||||
:items {:type "integer",
|
||||
:format "int64"}
|
||||
:x-nullable true}}
|
||||
{:in "path"
|
||||
:name :z
|
||||
:description ""
|
||||
:type "integer"
|
||||
:required true
|
||||
:format "int64"}]
|
||||
:responses {200 {:description ""
|
||||
:schema {:properties {:total {:format "int64"
|
||||
:type "integer"}}
|
||||
:required [:total]
|
||||
:type "object"}}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus with body"}}
|
||||
"/api/spec/plus/{z}" {:get {:parameters [{:description ""
|
||||
:format "int64"
|
||||
:in "query"
|
||||
:name "x"
|
||||
:required true
|
||||
:type "integer"}
|
||||
{:description ""
|
||||
:format "int64"
|
||||
:in "query"
|
||||
:name "y"
|
||||
:required true
|
||||
:type "integer"}
|
||||
{:in "path"
|
||||
:name "z"
|
||||
:description ""
|
||||
:type "integer"
|
||||
:required true
|
||||
:format "int64"}]
|
||||
:responses {200 {:description ""
|
||||
:schema {:properties {"total" {:format "int64"
|
||||
:type "integer"}}
|
||||
:required ["total"]
|
||||
:type "object"}}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus"}
|
||||
:post {:parameters [{:in "body",
|
||||
:name "",
|
||||
:description "",
|
||||
:required false,
|
||||
:schema {:type "array",
|
||||
:items {:type "integer",
|
||||
:format "int64"}
|
||||
:x-nullable true}}
|
||||
{:in "path"
|
||||
:name "z"
|
||||
:description ""
|
||||
:type "integer"
|
||||
:required true
|
||||
:format "int64"}]
|
||||
:responses {200 {:description ""
|
||||
:schema {:properties {"total" {:format "int64"
|
||||
:type "integer"}}
|
||||
:required ["total"]
|
||||
:type "object"}}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus with body"}}}}]
|
||||
:summary "plus"}
|
||||
:post {:parameters [{:in "body",
|
||||
:name "body",
|
||||
:description "",
|
||||
:required false,
|
||||
:schema {:type "array",
|
||||
:items {:type "integer",
|
||||
:format "int32"}
|
||||
:x-nullable true}}
|
||||
{:in "path"
|
||||
:name "z"
|
||||
:description ""
|
||||
:type "integer"
|
||||
:required true
|
||||
:format "int32"}]
|
||||
:responses {200 {:description ""
|
||||
:schema {:properties {"total" {:format "int32"
|
||||
:type "integer"}}
|
||||
:additionalProperties false
|
||||
:required ["total"]
|
||||
:type "object"}}
|
||||
400 {:schema {:type "string"}
|
||||
:description "kosh"}
|
||||
500 {:description "fail"}}
|
||||
:summary "plus with body"}}}}]
|
||||
(is (= expected spec))
|
||||
|
||||
(testing "ring-async swagger-spec"
|
||||
|
|
|
|||
Loading…
Reference in a new issue