HTTP API versioning support - wraps routes with version prefixes and headers.
SIDE EFFECTS:
Provides URL-based versioning (/api/v1/users, /api/v2/users) with:
HTTP API versioning support - wraps routes with version prefixes and headers. SIDE EFFECTS: - Route transformation - Response header modification - Logging Provides URL-based versioning (/api/v1/users, /api/v2/users) with: - Automatic version prefix wrapping - Version header injection (X-API-Version, X-API-Latest, X-API-Deprecated) - Backward compatibility (/api/users → /api/v1/users redirect) - Multiple version support concurrently
(apply-versioning api-routes config)The whole versioning step: what modules contribute as :api goes in
unversioned, and comes out prefixed with the default version plus a
backward-compatibility redirect for each path.
["/users" {:get …}] ;;=> ["/api/v1/users" {:get …}] and ["/api/users" {:get redirect}]
The version is read from [:active :wagoe/api-versioning :default-version].
The whole versioning step: what modules contribute as `:api` goes in
unversioned, and comes out prefixed with the default version plus a
backward-compatibility redirect for each path.
["/users" {:get …}]
;;=> ["/api/v1/users" {:get …}] and ["/api/users" {:get redirect}]
The version is read from `[:active :wagoe/api-versioning :default-version]`.(create-backward-compatibility-routes routes)(create-backward-compatibility-routes routes target-version)One /api/… redirect for every /api/<version>/… route given.
["/api/v1/users" …] --> ["/api/users" {:get redirect …}]
One `/api/…` redirect for every `/api/<version>/…` route given.
["/api/v1/users" …] --> ["/api/users" {:get redirect …}](create-redirect-route path target-version)A route at /api<path> that 307s to /api/<version><path>.
307 rather than 301: it preserves the method, so a POST stays a POST.
(create-redirect-route "/users" :v1) ;;=> ["/api/users" {:get {:handler …} :post {…} …}]
A route at `/api<path>` that 307s to `/api/<version><path>`.
307 rather than 301: it preserves the method, so a POST stays a POST.
(create-redirect-route "/users" :v1)
;;=> ["/api/users" {:get {:handler …} :post {…} …}]Default API versioning configuration.
Override in config.edn under :wagoe/api-versioning
Default API versioning configuration. Override in config.edn under :wagoe/api-versioning
(route-path route)The path of a Reitit route — [path data & children].
The path of a Reitit route — `[path data & children]`.
(version-config config)Get versioning configuration with defaults.
Args: config - Application config map
Returns: Version config map with defaults applied
Get versioning configuration with defaults. Args: config - Application config map Returns: Version config map with defaults applied
(version-headers-middleware handler version config)Middleware to add version headers to responses.
Adds headers:
Args: handler - Ring handler function version - Version keyword (:v1, :v2, etc.) config - Version configuration map
Returns: Wrapped Ring handler
Side Effects:
Example: (def handler (version-headers-middleware my-handler :v1 {:latest-stable :v2 :deprecated-versions #{:v1} :sunset-dates {:v1 "2026-06-01"}}))
(handler request) ;;=> {:status 200 ;; :headers {"X-API-Version" "v1" ;; "X-API-Version-Latest" "v2" ;; "X-API-Deprecated" "true" ;; "X-API-Sunset" "2026-06-01"} ;; :body ...}
Middleware to add version headers to responses.
Adds headers:
- X-API-Version: Current version (e.g., "v1")
- X-API-Version-Latest: Latest stable version
- X-API-Deprecated: "true" if version is deprecated
- X-API-Sunset: ISO 8601 date if sunset date exists
Args:
handler - Ring handler function
version - Version keyword (:v1, :v2, etc.)
config - Version configuration map
Returns:
Wrapped Ring handler
Side Effects:
- Response header modification
Example:
(def handler
(version-headers-middleware
my-handler
:v1
{:latest-stable :v2
:deprecated-versions #{:v1}
:sunset-dates {:v1 "2026-06-01"}}))
(handler request)
;;=> {:status 200
;; :headers {"X-API-Version" "v1"
;; "X-API-Version-Latest" "v2"
;; "X-API-Deprecated" "true"
;; "X-API-Sunset" "2026-06-01"}
;; :body ...}(with-route-path route path)route with its path replaced.
`route` with its path replaced.
(wrap-handler-with-version-headers handler config)Wrap Ring handler with version headers middleware.
Adds version headers to all responses.
Args: handler - Ring handler function config - Application config map
Returns: Wrapped Ring handler with version headers
Example: (def versioned-handler (wrap-handler-with-version-headers my-handler {:active {:wagoe/api-versioning {:default-version :v1 :latest-stable :v1}}}))
(versioned-handler request) ;;=> {:status 200 ;; :headers {"X-API-Version" "v1" ...} ;; :body ...}
Wrap Ring handler with version headers middleware.
Adds version headers to all responses.
Args:
handler - Ring handler function
config - Application config map
Returns:
Wrapped Ring handler with version headers
Example:
(def versioned-handler
(wrap-handler-with-version-headers
my-handler
{:active {:wagoe/api-versioning
{:default-version :v1
:latest-stable :v1}}}))
(versioned-handler request)
;;=> {:status 200
;; :headers {"X-API-Version" "v1" ...}
;; :body ...}(wrap-routes-with-version routes version)wrap-route-with-version over a vector of routes. Logs the count.
`wrap-route-with-version` over a vector of routes. Logs the count.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |