如何编写rails路由来映射带有主要版本和次要版本的版本化API,如/api/v1.2/users/1234

rya*_*ung 5 rest routes ruby-on-rails

我已经阅读了API版本化的最佳实践?.我同意将版本放在url路径而不是HTTP标头中.

为了实现这一点,我有一个像这样的命名空间控制器:

class Api::V1::UsersController < Api::BaseController
  def show
    ...
  end
end
Run Code Online (Sandbox Code Playgroud)

路线是:

current_api_routes = lambda do
  resource :users
end

namespace :api do
  namespace :v1, &current_api_routes
end
Run Code Online (Sandbox Code Playgroud)

然后rake routes我可以得到这样的路线:

api_v1_user GET    /api/v1/users/:id(.:format)                       api/v1/users#show
...
Run Code Online (Sandbox Code Playgroud)

我希望那个版本v1.2转到控制器v1.然后我可以在控制器中得到次要版本号,如下所示:

class Api::V1::UsersController < Api::BaseController
  def show
    minor_version = params[:minor_version] # minor_version = 2
    ...
  end
end
Run Code Online (Sandbox Code Playgroud)

有没有办法实现这个目标?

wve*_*gen 5

我们正在使用次要的API版本控制,但很小但可能会破坏更改(例如,允许null以前不允许的属性值).

# 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
Run Code Online (Sandbox Code Playgroud)