Hi, In my use case, I need to have different middle-ware for specific routes. This is the code:
(ns my-api.handler
(:require [compojure.api.sweet :refer :all]
[ring.util.http-response :refer :all]))
(defn echo0[handler]
(fn [request]
(prn "ECHO0" #_request)
(handler request)
))
(defn echo1[handler]
(fn [request]
(prn "ECHO1" #_request)
(handler request)
))
(def app
(api
(middleware [echo0] (swagger-routes))
(context "/api" []
:middleware [echo1]
(GET "/test" [] (ok "1")))))
However, when I run the code echo0
is invoked for /api/test
as well. Is there is any way to make those completely separate?@happy.lisper you might want to try the #ring-swagger channel, that’s where the Metosin guys hang out I think
ty
@happy.lisper if you want better control on when middleware is applied, there is also reitit-ring
. More verbose syntax with no default middleware. It implements route-first architecture: the mw chain is only applied if there is a full route match. Your example would be:
Thx for this option, I will definitely consider it as well.
there is #reitit to get help if you want to try that
(require '[reitit.ring :as ring])
(require '[reitit.swagger :as swagger])
(require '[reitit.swagger-ui :as swagger-ui])
(def app
(ring/ring-handler
(ring/router
[["/swagger.json"
{:get {:no-doc true
:middleware [echo0]
:handler (swagger/create-swagger-handler)}}]
["/api-docs/*"
{:no-doc true
:middleware [echo0]
:handler (swagger-ui/create-swagger-ui-handler)}]
["/api"
{:middleware [echo1]}
["/test"
{:get (fn [_]
{:status 200, :body "1"})}]]])))
(app {:request-method :get, :uri "/swagger.json"})
(app {:request-method :get, :uri "/api-docs/index.html"})
(app {:request-method :get, :uri "/api/test"})
… but you would need to add coercion, formatting etc. mw yourself. there are examples for it, but no things like api
from compojure-api.