TODO -- consider renaming this to [[metabase.api.handlers]]. | (ns metabase.api.util.handlers (:require [clojure.string :as str] [compojure.core :as compojure] [medley.core :as m] [metabase.api.macros :as api.macros] [metabase.api.open-api :as open-api])) |
(set! *warn-on-reflection* true) | |
(defn- split-path [^String path]
(when (some-> path (str/starts-with? "/"))
(if-let [next-slash-index (str/index-of path "/" 1)]
[(subs path 0 next-slash-index) (subs path next-slash-index (count path))]
[path "/"]))) | |
(defn- -route-map-handler [route-map]
(fn [request respond raise]
(if-let [[prefix rest-of-path] (split-path ((some-fn :path-info :uri) request))]
(if-let [handler (get route-map prefix)]
(let [request' (assoc request :path-info rest-of-path)]
(handler request' respond raise))
(respond nil))
(respond nil)))) | |
(defn- route-map->open-api-spec [route-map prefix]
(transduce
(map (fn [[next-prefix handler]]
(try
(open-api/open-api-spec handler (str prefix next-prefix))
(catch Throwable e
(throw (ex-info (format "Error generating dox in %s: %s" (pr-str next-prefix) (ex-message e))
{:prefix prefix, :next-prefix next-prefix}
e))))))
m/deep-merge
(sorted-map)
route-map)) | |
(declare route-map-handler) | |
(defn- prepare-route-map [route-map]
(update-vals route-map (fn [v]
(cond-> v
(map? v) route-map-handler
(simple-symbol? v) api.macros/ns-handler)))) | |
Create a Ring handler from a map of route prefix => handler. | (defn route-map-handler
[route-map]
(let [route-map (prepare-route-map route-map)]
(open-api/handler-with-open-api-spec
(-route-map-handler route-map)
(fn [prefix]
(route-map->open-api-spec route-map prefix))))) |
(defn- routes->open-api-spec [handlers prefix]
(transduce
(map (fn [handler]
(open-api/open-api-spec handler prefix)))
m/deep-merge
(sorted-map)
handlers)) | |
Replacement for [[compojure.core/routes]] that supports [[open-api-spec]]. | (defn routes
[& handlers]
(open-api/handler-with-open-api-spec
(apply #_{:clj-kondo/ignore [:discouraged-var]} compojure/routes handlers)
(fn [prefix]
(routes->open-api-spec handlers prefix)))) |