我正试着像Stripe一样对我的API进行版本控制。下面给出的是最新的API版本为2。
/api/users
向/api/v2/users
返回301
/api/v1/users
返回版本1的200个用户索引
/api/v3/users
向/api/v2/users
返回301
/api/asdf/users
向/api/v2/users
返回301
因此,基本上任何未指定版本的内容都会链接到最新版本,除非存在指定的版本,然后重定向到该版本。
这就是我到目前为止所知道的:
scope 'api', :format => :json do
scope 'v:api_version', :api_version => /[12]/ do
resources :users
end
match '/*path', :to => redirect { |params| "/api/v2/#{params[:path]}" }
end
发布于 2012-03-09 14:47:02
有几件事要补充:
你的重定向匹配对于某些路由是不起作用的-- *api
参数是贪婪的,会吞噬所有东西,例如/api/asdf/users/1
会重定向到/api/v2/1
。您最好使用像:api
这样的常规参数。诚然,它不能匹配像/api/asdf/asdf/users/1
这样的情况,但是如果你的应用程序接口中有嵌套的资源,这是一个更好的解决方案。
为什么你不喜欢namespace
?:-),例如:
current_api_routes = lambda do
resources :users
end
namespace :api do
scope :module => :v2, ¤t_api_routes
namespace :v2, ¤t_api_routes
namespace :v1, ¤t_api_routes
match ":api/*path", :to => redirect("/api/v2/%{path}")
end
这具有版本化和通用命名路由的附加好处。另请注意-使用:module
时的约定是使用下划线表示法,例如:api/v1
而不是'Api::V1‘。后者一度不起作用,但我相信它已经在Rails3.1中修复了。
此外,当您发布API的v3时,路由将像这样更新:
current_api_routes = lambda do
resources :users
end
namespace :api do
scope :module => :v3, ¤t_api_routes
namespace :v3, ¤t_api_routes
namespace :v2, ¤t_api_routes
namespace :v1, ¤t_api_routes
match ":api/*path", :to => redirect("/api/v3/%{path}")
end
当然,您的API很可能在不同版本之间具有不同的路由,在这种情况下,您可以这样做:
current_api_routes = lambda do
# Define latest API
end
namespace :api do
scope :module => :v3, ¤t_api_routes
namespace :v3, ¤t_api_routes
namespace :v2 do
# Define API v2 routes
end
namespace :v1 do
# Define API v1 routes
end
match ":api/*path", :to => redirect("/api/v3/%{path}")
end
发布于 2012-03-15 22:15:31
如果可能的话,我建议您重新考虑您的url,这样版本就不在url中,而是放在accepts头中。这个堆栈溢出的答案很好地解释了这个问题:
Best practices for API versioning?
这个链接准确地展示了如何使用rails路由实现这一点:
发布于 2012-11-22 07:58:40
我对按路由进行版本控制不是很感兴趣。我们构建VersionCake是为了支持更简单的应用程序接口版本控制。
通过在每个视图(jbuilder,RABL等)的文件名中包含API版本号,我们保持了版本控制的简洁性,并允许容易降级以支持向后兼容(例如,如果视图的v5不存在,我们将呈现视图的v4 )。
https://stackoverflow.com/questions/9627546
复制相似问题