ruby-on-rails - 如何编写rails路由以在路径中使用主要和次要版本映射版本化API,例如/api/v1.2/users/1234

标签 ruby-on-rails rest routes

我读过这个 Best practices for API versioning? .我同意将版本放在 url 路径而不是 HTTP header 中。

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

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

路线是:
current_api_routes = lambda do
  resource :users
end

namespace :api do
  namespace :v1, &current_api_routes
end

然后rake routes我可以得到这样的路线:
api_v1_user GET    /api/v1/users/:id(.:format)                       api/v1/users#show
...

我想要那个版本 v1.2转到 v1 的 Controller .然后我可以像这样在 Controller 中获得次要版本号:
class Api::V1::UsersController < Api::BaseController
  def show
    minor_version = params[:minor_version] # minor_version = 2
    ...
  end
end

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

最佳答案

我们正在使用次要 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

关于ruby-on-rails - 如何编写rails路由以在路径中使用主要和次要版本映射版本化API,例如/api/v1.2/users/1234,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14513950/

相关文章:

ruby-on-rails - 如何在Rails应用程序中实现虚名URL?

javascript - 如何让 AngularJS 响应导航

mysql - ActiveRecord 选择帐户中有 3 列的不同记录

java - Jersey JUnit 测试框架 - 错误状态 500

c# - 如何在每分钟循环一次Powershell直到条件成立?

rest - 带有 Location header 的 JAX-RS AsyncResponse.resume()

ruby-on-rails - 如何在清扫器中包含具有缓存过期的模块?

ruby-on-rails - 使用 selenium 作为 webdriver 的 Rails 集成测试 - 无法登录

ruby-on-rails - Rails 使用参数测试 Controller 私有(private)方法

angular - 如何让孙子在 Angular 6 中使用祖 parent <router-outlet>