This commit is contained in:
+23
-1
@@ -5,7 +5,12 @@
|
||||
[reitit.ring :as ring]
|
||||
[reitit.swagger :as swagger]
|
||||
[reitit.swagger-ui :as swagger-ui]
|
||||
[reitit.coercion]
|
||||
[reitit.coercion.malli :as malli]
|
||||
[reitit.ring.coercion :as coercion]
|
||||
[reitit.ring.middleware.exception :as exception]
|
||||
[reitit.ring.middleware.muuntaja :as muuntaja-middleware]
|
||||
[reitit.ring.middleware.parameters :as parameters]
|
||||
[muuntaja.core :as m]
|
||||
[tbd.health.routes :as health]
|
||||
[tbd.math.routes :as math]))
|
||||
@@ -21,6 +26,19 @@
|
||||
(and (map? (:body resp)) (nil? (:definitions (:body resp))))
|
||||
(update :body dissoc :definitions))))))
|
||||
|
||||
(defn- coercion-error-handler
|
||||
"Invalid request params -> 400 in the same EDN shape the routes use."
|
||||
[e _req]
|
||||
{:status 400
|
||||
:headers {"Content-Type" "application/edn; charset=utf-8"}
|
||||
:body (pr-str {:error "invalid request parameters"
|
||||
:details (:humanized (reitit.coercion/encode-error (ex-data e)))})})
|
||||
|
||||
(def ^:private exception-middleware
|
||||
(exception/create-exception-middleware
|
||||
(assoc exception/default-handlers
|
||||
:reitit.coercion/request-coercion coercion-error-handler)))
|
||||
|
||||
;; Each logical group (health, users, orders, ...) owns a `tbd.<group>.routes`
|
||||
;; namespace that returns its own route subtree; they're concatenated here.
|
||||
(def router
|
||||
@@ -37,7 +55,11 @@
|
||||
(health/routes)
|
||||
(math/routes)]
|
||||
{:data {:muuntaja m/instance
|
||||
:middleware [muuntaja-middleware/format-middleware]}}))
|
||||
:coercion malli/coercion
|
||||
:middleware [parameters/parameters-middleware
|
||||
muuntaja-middleware/format-middleware
|
||||
exception-middleware
|
||||
coercion/coerce-request-middleware]}}))
|
||||
|
||||
(def app
|
||||
(-> (ring/ring-handler
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
(ns tbd.math.routes
|
||||
(:require [tbd.math.core :as math]))
|
||||
|
||||
(defn- parse-num [s]
|
||||
(when s
|
||||
(or (parse-long s) (parse-double s))))
|
||||
;; :int first so "2" stays a long (a bare `number?` or :double would decode it to 2.0).
|
||||
;; The :swagger/* props make the spec say plain `number` instead of the first :or branch.
|
||||
(def ^:private number-schema
|
||||
[:or {:swagger/type "number" :swagger/format "double"} :int :double])
|
||||
|
||||
(defn- edn-response [status body]
|
||||
{:status status
|
||||
:headers {"Content-Type" "application/edn; charset=utf-8"}
|
||||
:body (pr-str body)})
|
||||
|
||||
(defn- add-handler [{:keys [query-params]}]
|
||||
(let [x (parse-num (get query-params "x"))
|
||||
y (parse-num (get query-params "y"))]
|
||||
(if (and x y)
|
||||
(edn-response 200 {:result (math/add x y)})
|
||||
(edn-response 400 {:error "x and y query params are required and must be numbers"}))))
|
||||
(defn- add-handler [{{{:keys [x y]} :query} :parameters}]
|
||||
(edn-response 200 {:result (math/add x y)}))
|
||||
|
||||
(defn routes []
|
||||
["/api/add"
|
||||
{:get {:tags ["math"]
|
||||
:summary "Add two numbers (?x=2&y=3 => {:result 5})"
|
||||
:parameters {:query [:map
|
||||
[:x {:description "First addend"} number-schema]
|
||||
[:y {:description "Second addend"} number-schema]]}
|
||||
:handler add-handler}}])
|
||||
|
||||
Reference in New Issue
Block a user