custom_header_versioning_constraint
🔍 Header-Based Version Negotiation Constraint
For truly flexible API versioning, implement a custom RouteConstraint
that inspects the Accept
header (or a custom header) to drive routing decisions. This allows you to route requests to different controller namespaces without polluting your URL space with version prefixes. You can also fallback to a default version if the header is missing.
# lib/constraints/api_version.rb
tclass ApiVersion
def initialize(version, default = false)
@version = version
@default = default
end
def matches?(req)
accept = req.headers['Accept']
if accept && accept.include?("application/vnd.myapp.v#{@version}+json")
true
else
@default
end
end
end
Then in config/routes.rb
:
Rails.application.routes.draw do
namespace :api do
scope module: :v1, constraints: ApiVersion.new(1, true) do
resources :posts
end
scope module: :v2, constraints: ApiVersion.new(2) do
resources :posts
end
end
end