penpot/backend/src/app/services/middleware.clj
2020-12-02 15:35:14 +01:00

72 lines
1.9 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns app.services.middleware
"Common middleware for services."
(:require
[app.common.exceptions :as ex]
[app.common.spec :as us]
[app.metrics :as mtx]
[clojure.spec.alpha :as s]
[cuerdas.core :as str]))
(defn wrap-spec
[handler]
(let [mdata (meta handler)
spec (s/get-spec (:spec mdata))]
(if (nil? spec)
handler
(with-meta
(fn [params]
(let [result (us/conform spec params)]
(handler result)))
(assoc mdata ::wrap-spec true)))))
(defn wrap-error
[handler]
(let [mdata (meta handler)]
(with-meta
(fn [params]
(try
(handler params)
(catch Throwable error
(ex/raise :type :service-error
:name (:spec mdata)
:cause error))))
(assoc mdata ::wrap-error true))))
(defn- get-prefix
[nsname]
(let [[_ _ c] (str/split nsname ".")]
c))
(defn wrap-metrics
[handler]
(let [mdata (meta handler)
nsname (namespace (:spec mdata))
smname (name (:spec mdata))
prefix (get-prefix nsname)
sname (str prefix "/" smname)
props {:id (str/join "__" [prefix
(str/snake smname)
"response_time"])
:help (str "Service timing measures for: " sname ".")}]
(with-meta
(mtx/wrap-summary handler props)
(assoc mdata ::wrap-metrics true))))
(defn wrap
[handler]
(-> handler
(wrap-spec)
(wrap-error)
(wrap-metrics)))