1

In my Compojure/Ring web application's handler, I need to serve one set of routes using the site-defaults middleware, and another separate set of routes using the api-defaults middleware. How can I do that?

The code below only serves one set of routes using the site-defaults middleware. What should I add to serve the second set of routes (api-routes) using the api-defaults middleware?

(web-experiment.handler
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults
                                              site-defaults
                                              api-defaults]]
            [web-experiment.views :refer :all]))

(defroutes app-routes
  (GET "/" [] (index-page))
  (GET "/about" [] (about-page))
  (route/not-found "Not Found"))

(defroutes api-routes
  (GET "/grapefruit" [:as {body :body}] (grapefruit-api body))
  (GET "/factory" [:as {body :body}] (factory-api body))
  (GET "/umbrella" [:as {body :body}] (umbrella-api body))
  (route/not-found "Not Found"))

(def app
  (wrap-defaults app-routes site-defaults))
;; TODO: Add api-routes. How to use api-defaults middleware to serve api-routes?

I've read these:

Flux
  • 9,805
  • 5
  • 46
  • 92

2 Answers2

0

You can just wrap some of your routes in one wrapper and some others in the other wrapper. You just need to organize your routes a bit differently.

Some time ago I wrote a demo what you can do with ring routes. You can find it at https://github.com/ska2342/ring-routes-demo/

In particular the part starting at line 70 of the demo should be interesting to you.

Stefan Kamphausen
  • 1,615
  • 15
  • 20
-2

I'm not sure how this could be solved in Compojure, but you may wish to consider using Pedestal. This page provides a good introduction to the route matching process, which takes place before any interceptors are called (the Pedestal replacement for Ring middleware).

So you could define two different sets of middleware:

(def user-intc-chain [inject-connection auth-required (body-params/body-params)] )
(def api-intc-chain  [inject-connection auth-required api-params-intc] )

and then define routes like:

["/echo"   :get (conj user-intc-chain echo-intc) ] ; a "user" route
["/alive?" :get (conj api-intc-chain alive-intc) ] ; an "api" route

In addition to the built-in Pedestal features, I have a number of helper & convenience functions documented here: https://cloojure.github.io/doc/tupelo/tupelo.pedestal.html

Alan Thompson
  • 29,276
  • 6
  • 41
  • 48