如何通过应用程序 mime - Rails 提供最新的 API
How to serve the latest API through application mime - Rails
考虑以下因素
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :users
resources :profiles
end
namespace :v2 do
resources :users
resources :profiles
end
end
而不是路由到 api/v1 和 api/v2,我想要的是将接受 header 设置为使用我希望它服务的任何一个并使用路径 api
忽略版本。
所以如果我将它设置为服务 api/v1 路径应该只是 localhost:3000/api
我正在观看这个 railcasts 视频
http://railscasts.com/episodes/350-rest-api-versioning?autoplay=true
但查看评论时,代码和解决方案有时会出现各种问题。
目前最好的解决方案是什么?
来自 link
的回复
Each time you create a new MIME type name (application/vnd.example.v1, application/vnd.example.v2, ...),
a kitten is hurt! don't do that! that's bad!
Use MIME parameters instead: application/vnd.example; version=1, application/vnd.example; version=2, ...
(version=, or level=, or v= or whatever you want, this is part of your design).
The semantic of a MIME type is that every document "flagged" with that type share the same "lineage",
and that two different names are not related, even if they share a same prefix.
By incorporating a version identifier into the MIME type name,
you are making the names distinct and are in the same case as if your V1 API was using text/html documents
whereas your V2 now uses image/png pictures instead.
The problem with the default is it will accept any mime type, as it will only check the boolean and not the string:
@default || req.headers['Accept'].include?("application/vnd.example.v#{@version}")
I mean, if we're expecting "application/vnd.github.v1", it will also accept "application/vnd.twitter.v1"
我已经在几个项目中使用了 Railscast 中描述的方法,并且没有遇到任何问题。我认为这是一个非常好的和最新的解决方案。
将其放在您的 /lib 目录中:
class ApiConstraints
def initialize(options)
@version = options[:version]
@default = options[:default]
end
def matches?(req)
@default || req.headers['Accept'].include?("application/vnd.yourdomain.v#{@version}")
end
end
然后定义你的路线如下:
namespace :api, defaults: {format: 'json'} do
scope module: :v1, constraints: ApiConstraints.new(version: 1) do
resources :users
resources :profiles
end
scope module: :v2, constraints: ApiConstraints.new(version: 2, default: true) do
resources :users
resources :profiles
end
end
您现在可以使用以下端点访问 API:
https://www.yourdomain.com/api/users
https://www.yourdomain.com/api/profiles
默认情况下将提供版本 2。
或者您可以设置接受 header,例如:
Accept: application/vnd.yourdomain.v1
您将获得版本 1。
这有什么问题吗?
考虑以下因素
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :users
resources :profiles
end
namespace :v2 do
resources :users
resources :profiles
end
end
而不是路由到 api/v1 和 api/v2,我想要的是将接受 header 设置为使用我希望它服务的任何一个并使用路径 api
忽略版本。
所以如果我将它设置为服务 api/v1 路径应该只是 localhost:3000/api
我正在观看这个 railcasts 视频
http://railscasts.com/episodes/350-rest-api-versioning?autoplay=true
但查看评论时,代码和解决方案有时会出现各种问题。
目前最好的解决方案是什么?
来自 link
的回复 Each time you create a new MIME type name (application/vnd.example.v1, application/vnd.example.v2, ...),
a kitten is hurt! don't do that! that's bad!
Use MIME parameters instead: application/vnd.example; version=1, application/vnd.example; version=2, ...
(version=, or level=, or v= or whatever you want, this is part of your design).
The semantic of a MIME type is that every document "flagged" with that type share the same "lineage",
and that two different names are not related, even if they share a same prefix.
By incorporating a version identifier into the MIME type name,
you are making the names distinct and are in the same case as if your V1 API was using text/html documents
whereas your V2 now uses image/png pictures instead.
The problem with the default is it will accept any mime type, as it will only check the boolean and not the string:
@default || req.headers['Accept'].include?("application/vnd.example.v#{@version}")
I mean, if we're expecting "application/vnd.github.v1", it will also accept "application/vnd.twitter.v1"
我已经在几个项目中使用了 Railscast 中描述的方法,并且没有遇到任何问题。我认为这是一个非常好的和最新的解决方案。
将其放在您的 /lib 目录中:
class ApiConstraints
def initialize(options)
@version = options[:version]
@default = options[:default]
end
def matches?(req)
@default || req.headers['Accept'].include?("application/vnd.yourdomain.v#{@version}")
end
end
然后定义你的路线如下:
namespace :api, defaults: {format: 'json'} do
scope module: :v1, constraints: ApiConstraints.new(version: 1) do
resources :users
resources :profiles
end
scope module: :v2, constraints: ApiConstraints.new(version: 2, default: true) do
resources :users
resources :profiles
end
end
您现在可以使用以下端点访问 API:
https://www.yourdomain.com/api/users
https://www.yourdomain.com/api/profiles
默认情况下将提供版本 2。
或者您可以设置接受 header,例如:
Accept: application/vnd.yourdomain.v1
您将获得版本 1。
这有什么问题吗?