ring

2018-09-20T05:40:36.000100Z

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?

borkdude 2018-09-20T15:16:10.000100Z

@happy.lisper you might want to try the #ring-swagger channel, that’s where the Metosin guys hang out I think

2018-09-20T15:16:23.000100Z

ty

ikitommi 2018-09-20T21:05:06.000100Z

@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:

2018-09-22T00:00:01.000100Z

Thx for this option, I will definitely consider it as well.

ikitommi 2018-09-24T18:12:59.000100Z

there is #reitit to get help if you want to try that

ikitommi 2018-09-20T21:05:16.000100Z

(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"})

ikitommi 2018-09-20T21:07:25.000100Z

… but you would need to add coercion, formatting etc. mw yourself. there are examples for it, but no things like api from compojure-api.