clojuremiddlewarecompojureringcompojure-api

Compojure & Ring Middleware Always Returns 404


I'm trying to set up a simple middleware in a luminus project that uses compojure and ring. I'm sure I'm missing something simple, but I've set up a simple middleware to test and I'm not getting the results I expect.

(defn wrap-api-auth [handler]
  (if (= 2 2)
  (unauthorized {:body "unauthorized"})
  handler))

I would expect this to give back a 401, but it keeps returning a 404. If I change the if expressions (= 2 3) the route fires correctly. For reference, here's the route, it's one of the default that luminus generates with the middleware added.

(GET "/plus" []
      :return       Long
      :middleware [wrap-api-auth]
      :query-params [x :- Long, {y :- Long 1}]
      :summary      "x+y with query-parameters. y defaults to 1."
      (ok (+ x y)))

Solution

  • A handler is a function from request to response.

    A middleware is a function that takes a handler and returns another handler wrapping the first.

    Your wrap-api-auth gets called when your service starts up, does its check, and if the check returns true, stores a response as a handler, and then each request gets handled by a constant response instead of a handler. Since a response is a map, and maps in Clojure can be used as functions, this does probably not produce a helpful error but just returns nil, which is then treated as "not found".

    Schematically, your wrapper should maybe look like this:

    (defn wrap-api-auth [handler]
      (fn [request]
        (if (check-authorization request)
          (handler request)     ; pass to wrapped handler
          (unauthorized …))))   ; do something else