diff --git a/src/tbd/core.clj b/src/tbd/core.clj index f5e1388..cb01456 100644 --- a/src/tbd/core.clj +++ b/src/tbd/core.clj @@ -10,6 +10,17 @@ [tbd.health.routes :as health] [tbd.math.routes :as math])) +(defn- swagger-handler + "reitit emits `\"definitions\": null` when no route declares a schema, which + violates the Swagger 2.0 schema (must be an object) and makes validators reject the spec." + [] + (let [handler (swagger/create-swagger-handler)] + (fn [req] + (let [resp (handler req)] + (cond-> resp + (and (map? (:body resp)) (nil? (:definitions (:body resp)))) + (update :body dissoc :definitions)))))) + ;; Each logical group (health, users, orders, ...) owns a `tbd..routes` ;; namespace that returns its own route subtree; they're concatenated here. (def router @@ -17,7 +28,7 @@ [["/swagger.json" {:get {:no-doc true :swagger {:info {:title "tbd API" :version "1.0.0"}} - :handler (swagger/create-swagger-handler)}}] + :handler (swagger-handler)}}] ["/" {:get {:no-doc true :handler (fn [_req] {:status 200 diff --git a/test/tbd/core_test.clj b/test/tbd/core_test.clj index b301fb7..1ec5680 100644 --- a/test/tbd/core_test.clj +++ b/test/tbd/core_test.clj @@ -22,7 +22,9 @@ (deftest swagger-spec-test (let [resp (request :get "/swagger.json")] (is (= 200 (:status resp))) - (is (re-find #"/api/ping" (slurp (:body resp)))))) + (is (re-find #"/api/ping" (slurp (:body resp)))) + (is (not (re-find #"\"definitions\":null" (slurp (:body (request :get "/swagger.json"))))) + "a null `definitions` makes the spec invalid Swagger 2.0"))) (deftest unknown-route-test (is (= 404 (:status (request :get "/nope")))))