7

I've read this Best practices for API versioning?. And I agree with putting the version in url path rather than in HTTP header.

In order to implement this, I have a namespaced controller like this:

class Api::V1::UsersController < Api::BaseController
  def show
    ...
  end
end

And the route are:

current_api_routes = lambda do
  resource :users
end

namespace :api do
  namespace :v1, &current_api_routes
end

Then rake routes I can get routes like this:

api_v1_user GET    /api/v1/users/:id(.:format)                       api/v1/users#show
...

I want that version v1.2 goes to controller of v1. Then I can get minor version number in controller like this:

class Api::V1::UsersController < Api::BaseController
  def show
    minor_version = params[:minor_version] # minor_version = 2
    ...
  end
end

Is there a way to achieve this?

Community
  • 1
  • 1
ryancheung
  • 2,999
  • 3
  • 24
  • 25
  • The answer really depends on what you're going to do with this minor version afterwards. What is the purpose of having this? – Ryan Bigg Jan 25 '13 at 01:48
  • I want this to manage both major and minor version of APIs. It means if API get little changes I just bump the minor version, not the major version which was handled by a namespaced controller, so I would not get too many controllers after a few minor changed. – ryancheung Jan 25 '13 at 02:11

1 Answers1

5

We are using minor API versioning for small but possibly breaking changes (like allowing null values for an attribute that previously wouldn't be allowed to be so).

# config/routes.rb
My::Application.routes.draw do
  namespace :api do
    scope "v:api_version", module: "v1", as: "v1", constraints: { api_version: /1(\.[0123]?)/ } do
      resources :users
    end
  end
end

# app/controllers/api/application_controller.rb
class API::ApplicationController < ActionController::Base
  private
  def api_version
    @api_version ||= begin
      major, minor = params[:api_version].split('.', 2).map(&:to_i)
      OpenStruct.new(major: major, minor: minor || 0)
    end
  end
end

# app/controllers/api/v1/users_controller.rb
class API::V1::UsersController < API::ApplicationController
  def show
    # ...
    something_more if api_version.minor >= 2
  end
end
wvengen
  • 383
  • 4
  • 10