-
Notifications
You must be signed in to change notification settings - Fork 0
/
route.clj
64 lines (61 loc) · 2.48 KB
/
route.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
(ns corbihttp.interceptor.route
(:require [bidi.bidi :as bidi]
[corbihttp.metric :as metric]
[corbihttp.log :as log]
[exoscale.ex :as ex]
[exoscale.interceptor :as itc])
(:import io.micrometer.core.instrument.Timer))
(defn dispatch-map->bidi
[dispatch-map]
["/"
(->> dispatch-map
(map (fn [[handler config]]
[(:path config) (if-let [method (:method config)]
{method handler}
handler)]))
(into {}))])
(defn route!
[{:keys [request] :as ctx}
{:keys [dispatch-map registry router handler-component not-found-handler]}]
(let [uri (str (:uri request))
method (-> request :request-method name)
request (bidi/match-route* router
(:uri request)
request)
req-handler (:handler request)]
(if (get dispatch-map req-handler)
(assoc ctx
:request request
:start-time (when registry
(java.time.Instant/now))
:handler req-handler
:timer (when registry
(metric/get-timer! registry
:http.request.duration
{"uri" uri
"method" method})))
(do (log/warnf {}
"uri %s not found for method %s"
uri method)
;; TODO: why terminate is not working ?
(comment
(itc/terminate (assoc ctx :response
(not-found-handler handler-component request))))
(throw (ex/ex-info (format "uri %s not found for method %s"
uri method)
[::not-found [:corbi/user ::ex/not-found]]))))))
(defn route
"This set the :handler request value based on the request and the dispatch map."
[{:keys [dispatch-map] :as params}]
(let [router (dispatch-map->bidi dispatch-map)]
{:name ::main-handler
:enter (fn [ctx]
(route! ctx
(assoc params
:router router)))
:leave (fn [ctx]
(when-let [start-time (:start-time ctx)]
(let [end (java.time.Instant/now)]
(.record ^Timer (:timer ctx)
(java.time.Duration/between start-time end)))
ctx))}))