anyone know if it's possible to version routes using ring and compojure?
@dbernal Are you thinking about passing API version in query string / form data, rather than embed the version in the URI itself? (i.e., GET <https://api.acme/data?version=2>
vs GET <https://api.acme/v2/data>
)
@seancorfield yes. As a header param
You'd have to write some middleware for that, but it would be fairly straightforward.
If you had your Compojure routes set up grouped under "/v1"
and "/v2"
then you could have middleware that looked for the header and updated the :uri
field in the Ring Request (before the Compojure middleware gets control)
Assuming your routes are different for the different versions...
gotcha. So the only way to do it would be to have separate compojure routes?
If the routes for V1 and V2 are different, you still have to define both.
If the routes are identical for V1 and V2, then just check the version inside your handler(s).
(I'm puzzled by your response so perhaps I'm misunderstanding your original question)
I would do something like:
(defn on-version [versions]
(fn [request]
(let [version (get-in request [:headers "x-version"])
handler (get versions version (constantly nil))]
(handler request))))
(GET "/ping" []
(on-version
{"v1" (fn [req] ...)
"v2" (fn [req] ...)}))
@seancorfield sorry. I misunderstood. I thought you meant that if they were the same route then I would need to look at the headers and dispatch it to another compojure route but it seems like it just needs to be dispatched to a certain handler. I can kind of see that from @ikitommi's example. If I was using the compojure api would it be something similar?
compojure-api
instead of compojure
? I don't know, I've never used the former. I've only ever used the latter.
ah, I see. ok, I'll dig around a little bit more