优雅的Rails API版本控制

6
目前,我正在为我们的Rails应用程序的REST API实现版本控制。是否有一种方法可以实现仅在新版本中定义新功能? 比如说:我有一个用户控制器和一个产品控制器。在V1和V2之间,产品保持不变,但用户已更改。如果我调用产品的V2版本,我的应用程序知道它不存在,只需使用最新的控制器版本(在这种情况下是V1)。这将允许我们不为每个版本创建一个全新的控制器集合; 我们只会为已更改的特定功能创建新控制器。
以下是我们Routes.rb中的代码片段,我承认我不知道如何解决这个问题。非常感谢您的帮助!
namespace :api do
    scope module: :v1, constraints: ApiConstraints.new(version: 1) do
      resources :users
      resources :products
    end
    scope module: :v2, constraints: ApiConstraints.new(version: 2) do
      resources :users
    end 
end
3个回答

2

我一直使用同样的策略,最近改变了方法 - 并且坦率地说,我有偏见,因为我也是我们新方法的作者之一,使用了VersionCake

这种方法是仅对负载或视图进行版本控制,毕竟视图是客户端和服务端之间的契约,如果有破坏性的契约变更,则需要更改版本。在VersionCake中,您可以像这样对视图进行版本控制:

app/views/products/show.v1.rabl
app/views/products/show.v2.rabl
app/views/users/show.v1.rabl

根据您的问题,重要的具体特点是VersionCake可以优雅地降级到最新支持的版本。以上面的示例为例,客户端请求版本2的users/1.json将接收users/show.v1.rabl的有效负载。尽管如此,这需要采用一种新的版本控制方法,因此可能不是最佳答案,但我认为这是值得考虑的选项。

这看起来很有趣,我想问一下,您是否曾经需要创建一个新的控制器,因为旧的控制器有太多特定于版本的条件?如何按版本缓存?谢谢。 - lulalala
我在控制器中开发了几个版本分支,但没有什么过分的地方需要创建一个新的控制器。我们将尝试将尽可能多的版本特定逻辑强制到模型方法中,并在视图中调用它们,以尽可能使控制器保持DRY。至于缓存,这取决于您指的是哪种类型。如果使用页面缓存,则应该在ETag中使用版本。 - bencode

1

你已经看过Grape了吗?

我所做的关于API的事情是,当所有API(如身份验证)发生变化时,我只需让它们都继承自特定版本的API控制器,例如Api::V1::BaseController,并将公共行为和控件放在那里。

由于更改API通常也意味着更改表示形式,因此使用生成表示形式的工具也非常重要,有许多宝石可以用于此:


谢谢您的快速回复!我们的团队已经在使用RABL,所以理想情况下我们希望在Grape中重用这些视图。我现在正在研究Grape,一旦我有一个可行的实现,我会将其标记为答案。 - NSCodeCasts

1

Grape 的设计目的是什么。

此外,您可以选择在 routes.rb 文件中挂载 API 或在 config.ru 中映射它,绕过 Rails 栈并大大提高 API 的性能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接