如何通过应用程序 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。

这有什么问题吗?