Question

I am trying to write a middleware for converting all the string object ids in the request to ObjectId objects.

I am achieving this using the following:

(defn get-object-id
  [id]
  (when (and (string? id) (re-matches object-id-regex id))
    (ObjectId. id)))

(defn maybe-obj->object-id [obj]
  (or (get-object-id obj) obj))

(defn- convert-string->object-ids [obj]
  (cwalk/postwalk
    (partial pcommon/maybe-obj->object-id) obj))

(defn warp-params-string->objectid
  "convert strings to object ids"
  [handler]
  (fn [request]
    (handler (update-in request [:params] convert-string->object-ids))))

This is working for all the params coming for json, request params etc. But this is not applying to the route params, e.g. :fst for url "/:fst". I looked at the GET macro and the route params are being injected somewhere inside that macro. However since GET/POST etc are executed last, my middlewares do not have access to these. Any graceful way of achieving this.

Was it helpful?

Solution

Those /:foo/:bar-style parameters get bound as a result of pattern matching on URIs, with the patterns specified in the individual routes' definitions. Outer layers don't even know what the patterns look like. So, not really possible to lift processing of these to middleware.

Instead, you could write a macro, say with-preprocessed-params, to wrap your route handlers' bodies in. If it ends up being useful in many handlers, you can additionally provide your own versions of GET & Co., delegating to Compojure's macros with the body wrapped in your param-processing macro.

That's not really a good solution if you were hoping to use the results of this preprocessing in further layers of middleware. In that case, assuming you're happy to leave matching actual URI path segments to the core handler layer, you can perform your preprocessing of other parameter types in a piece of middleware, then use your GET & Co. variants to preprocess the route parameters only.

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