Versioning your HTTP API - Ruby on Rails example
If you’re interested in why this example is here, this is the post it originated from: Versioning your HTTP API
You probably know this has to go in your config/routes.rb
file somewhere, but
where exactly? What you’re going to need to do is scope your API routes with a
Constraint.
If your constraint’s matches? method returns true, then that scope’s routes
will be applied to the incoming request. Here’s a class that you can put in
lib/api_constraints.rb
which will match on the application/vnd.my_app.v1
header:
class APIConstraints
def initialize(options)
@version = options[:version]
@default = options[:default]
end
def matches?(req)
req.headers["Accept"].include?(media_type) || @default
end
private
def media_type
"application/vnd.my_app.v#{@version}"
end
end
In your routes file, you make use of it like so:
require "api_constraints" # you need to import the class from lib
Rails.application.routes.draw do
scope module: :v1, constraints: APIConstraints.new(version: 1) do
resources :users
end
scope module: :v2, constraints: APIConstraints.new(version: 2, default: true) do
resources :users
resources :comments
end
end
Here we have two versions of our API (v1 and v2). v2 is currently the default API version that will be used.
The module
declaration on the scope is also worth mentioning. It allows you to
put your version-specific code in modules of the same name. For example, this
is how I’d define the controllers:
class V1::UsersController < ApplicationController
end
class V2::UsersController < ApplicationController
end
And that’s it! Very easy to manage through the routes file. You can add new versions and change the default with ease.