REST API 版本控制 - 为啥不对模型进行版本控制

Posted

技术标签:

【中文标题】REST API 版本控制 - 为啥不对模型进行版本控制【英文标题】:REST API versioning - why aren't models versionedREST API 版本控制 - 为什么不对模型进行版本控制 【发布时间】:2016-03-08 15:11:47 【问题描述】:

我一直在阅读有关版本 REST API 的所有方法。在几乎所有实现中,控制器和视图都是版本化的,但模型不是。

以 rails 为例,控制器组织为:

# app/controllers/api/v1/events_controller.rb
class Api::V1::EventsController < Api::ApiController

end

在不同版本目录中的相应视图也是如此。为什么我们不对模型进行版本化?是因为我们希望我们的模型(底层数据库模式)不会随着 API 的发展而改变吗?当我重命名数据库中的列名并需要一个新模型来解决这个问题时会发生什么?

【问题讨论】:

【参考方案1】:

模型是应用程序内部的一部分,而不是其公共 API。版本控制的关键是输入/输出不偏离。

在数据库中维护不同版本的数据 - 例如,属于 API 不同版本的数据不是特别吸引人或实用。

因此,您可以使用适配器/序列化器来调整输入/输出以适应特定版本的 API,而内部则以当前版本运行。

假设您匆忙发布了 API v 1:

GET api/v1/users/:id
  username (String)
  first_name (String)
  lastname (String)

发布后,您意识到命名不一致。 因此,您将创建一个将 lastname 重命名为 last_name 的迁移。

因此 API 版本 2 将具有以下签名:

GET api/v2/users/:id
  username (String)
  first_name (String)
  last_name (String)

但这应该会破坏对API v1 的测试,因为响应不再包含lastname

所以要修复它,我们将创建如下内容:

class Api::V1::UserSerializer < ActiveModel::Serializer
  attributes :username, :first_name, :lastname

  def lastname
    object.last_name
  end
end

【讨论】:

这个例子对于 GET 用例来说太具体了,在这里很好用。你能回答这个吗 - ***.com/questions/56303966/…? @ayyappa 你想要什么?你的问题有一个很好的答案【参考方案2】:

我们为什么不对模型进行版本化?

模型通常与数据库架构紧密结合。通常,数据库是所有版本的 API 共享的规范数据存储,因此对模型进行版本控制没有多大意义。

另外,在 Rails 应用程序中,大部分业务逻辑通常驻留在模型中。版本控制模型需要复制逻辑或添加另一个抽象层,这会引入维护开销。

是因为我们希望我们的模型(底层数据库架构)不会随着 API 的发展而改变吗?

没有。数据库架构可以而且确实经常更改。

当我重命名数据库中的列名并需要一个新模型来解决这个问题时会发生什么?

您不会引入模型来解释架构更改。您调整现有模型以适应更改,然后修改先前 API 的实现,以便先前版本的客户端继续以与之前预期相同的格式获得响应。

由于您的业务实体(模型)到 API 响应的这种映射发生在控制器(或序列化程序或 json 模板 - 取决于您的首选实现)中——您的应用程序的这些部分必须进行修改以确保向后兼容性.

【讨论】:

以上是关于REST API 版本控制 - 为啥不对模型进行版本控制的主要内容,如果未能解决你的问题,请参考以下文章

像 Twilio 那样按日期对 REST api 进行版本控制有啥好处?

使用 Guice 3.0 + JaxRS 2.0 对 REST API 进行版本控制

Spring Boot REST API 版本控制的自定义标头方法

REST api 版本控制在技术上是如何实现的? [关闭]

REST api 版本控制(仅版本表示,而不是资源本身)

无需重复代码的 REST api 最佳实践版本控制