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)Apply API versioning to routes.
Takes unversioned API routes and returns versioned routes with:
Args: api-routes - Vector of normalized API route maps (unversioned) config - Application config map
Returns: Vector of versioned and redirect routes
Side Effects:
Example: (apply-versioning [{:path "/users" :methods {:get {...}}} {:path "/items" :methods {:get {...}}}] {:active {:wagoe/api-versioning {:default-version :v1 :latest-stable :v1 :supported-versions #{:v1}}}}) ;;=> [{:path "/api/v1/users" ...} ;; {:path "/api/v1/items" ...} ;; {:path "/api/users" :methods {:get redirect-handler ...}} ;; {:path "/api/items" :methods {:get redirect-handler ...}}]
Apply API versioning to routes.
Takes unversioned API routes and returns versioned routes with:
- Version prefix (/api/v1/users)
- Version headers middleware
- Backward compatibility redirects
Args:
api-routes - Vector of normalized API route maps (unversioned)
config - Application config map
Returns:
Vector of versioned and redirect routes
Side Effects:
- Route transformation
- Logging
Example:
(apply-versioning
[{:path "/users" :methods {:get {...}}}
{:path "/items" :methods {:get {...}}}]
{:active {:wagoe/api-versioning
{:default-version :v1
:latest-stable :v1
:supported-versions #{:v1}}}})
;;=> [{:path "/api/v1/users" ...}
;; {:path "/api/v1/items" ...}
;; {:path "/api/users" :methods {:get redirect-handler ...}}
;; {:path "/api/items" :methods {:get redirect-handler ...}}](create-backward-compatibility-routes routes)(create-backward-compatibility-routes routes target-version)Create redirect routes for backward compatibility.
Generates /api/* routes that redirect to /api/v1/* for all existing routes.
Args: routes - Vector of normalized route maps (versioned) target-version - Version to redirect to (default :v1)
Returns: Vector of redirect route maps
Side Effects:
Example: (create-backward-compatibility-routes [{:path "/api/v1/users" ...} {:path "/api/v1/items" ...}] :v1) ;;=> [{:path "/api/users" :methods {:get redirect-handler ...}} ;; {:path "/api/items" :methods {:get redirect-handler ...}}]
Create redirect routes for backward compatibility.
Generates /api/* routes that redirect to /api/v1/* for all existing routes.
Args:
routes - Vector of normalized route maps (versioned)
target-version - Version to redirect to (default :v1)
Returns:
Vector of redirect route maps
Side Effects:
- Logging
Example:
(create-backward-compatibility-routes
[{:path "/api/v1/users" ...}
{:path "/api/v1/items" ...}]
:v1)
;;=> [{:path "/api/users" :methods {:get redirect-handler ...}}
;; {:path "/api/items" :methods {:get redirect-handler ...}}](create-redirect-route path target-version)Create redirect route from unversioned path to versioned path.
Creates a route that redirects /api/users → /api/v1/users (307 Temporary Redirect)
Args: path - Unversioned path (e.g., "/users") target-version - Version to redirect to (e.g., :v1)
Returns: Normalized route map with redirect handler
Example: (create-redirect-route "/users" :v1) ;;=> {:path "/api/users" ;; :methods {:get {:handler (fn [req] ;; {:status 307 ;; :headers {"Location" "/api/v1/users"}})} ;; :post {...} ;; :put {...} ;; :delete {...}}}
Create redirect route from unversioned path to versioned path.
Creates a route that redirects /api/users → /api/v1/users (307 Temporary Redirect)
Args:
path - Unversioned path (e.g., "/users")
target-version - Version to redirect to (e.g., :v1)
Returns:
Normalized route map with redirect handler
Example:
(create-redirect-route "/users" :v1)
;;=> {:path "/api/users"
;; :methods {:get {:handler (fn [req]
;; {:status 307
;; :headers {"Location" "/api/v1/users"}})}
;; :post {...}
;; :put {...}
;; :delete {...}}}Default API versioning configuration.
Override in config.edn under :wagoe/api-versioning
Default API versioning configuration. Override in config.edn under :wagoe/api-versioning
(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 ...}(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 all routes with version prefix.
Args: routes - Vector of normalized route maps version - Version keyword (:v1, :v2, etc.)
Returns: Vector of routes with version prefix
Side Effects:
Example: (wrap-routes-with-version [{:path "/users" :methods {:get {...}}} {:path "/items" :methods {:get {...}}}] :v1) ;;=> [{:path "/api/v1/users" ...} ;; {:path "/api/v1/items" ...}]
Wrap all routes with version prefix.
Args:
routes - Vector of normalized route maps
version - Version keyword (:v1, :v2, etc.)
Returns:
Vector of routes with version prefix
Side Effects:
- Logging
Example:
(wrap-routes-with-version
[{:path "/users" :methods {:get {...}}}
{:path "/items" :methods {:get {...}}}]
:v1)
;;=> [{:path "/api/v1/users" ...}
;; {:path "/api/v1/items" ...}]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 |