Question

I have a ring middleware which does some check on request maps with the header values. For the check I have to hit the database.

If a defroutes as a set of routes starting with acommon URI pattern. I don't want a middleware to run for any random URL that matches the pattern before getting handled.

I only want middleware to run for a certain set of URIs that I am suing inside of defroutes only. The reason being there is a database access in the middleware which I want to avoid for 404 responses having the same pattern.

Was it helpful?

Solution

Here is comporoute, a ring handler without any macro magic, aimed at composability and extensibility.

Even though it's in early alpha state it has precise docstrings already. It has a feature called inner middleware to solve the issue you are having. You may (and should) use it only for what you need it for and leave the rest to Compojure.

Given your Compojure handler/app is called compojure:

(defn demo-middleware 
  "A test midleware associng :bar to :foo of request"
  [handler]
  (fn [request]
    (handler (assoc request :foo :bar))))

(defn demo-handler [request]
  (ring.util.response/response 
     (str "id is " (get-in request [:params :id]) " "
          ":foo is" (:foo request))))

(def app
  (comporoute.core/router
    [["/demo-with-middleware"
      [demo-middleware ;; all handlers in this vector are 
                       ;; wrapped via demo-middleware
       ["/:id" :demo-with demo-handler]]]
     ["/demo-without-middleware" 
       ["/:id" :demo-without demo-handler]]]
    :page-not-found compojure)

At the shell

curl http://localhost:8080/demo-without-middleware/1234
id is 1234 :foo is

curl http://localhost:8080/demo-with-middleware/1234
id is 1234 :foo is :bar

# Everything else will be handled by compojure.

Dependency vector [comporoute "0.2.0"]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top