REST API 版本控制 - 为什么模型没有版本控制
REST API versioning - why aren't models versioned
我一直在阅读 REST APIs 版本的所有方法。在几乎所有的实现中,控制器和视图都是版本化的,但模型不是。
以 rails 为例,控制器组织为:
# app/controllers/api/v1/events_controller.rb
class Api::V1::EventsController < Api::ApiController
end
相应的视图也放在不同版本的目录中。我们为什么不版本模型?是因为我们希望我们的模型(底层数据库模式)不会随着 API 的发展而改变吗?当我重命名数据库中的列名并需要一个新模型来解决这个问题时会发生什么?
模型是应用程序内部的一部分,而不是它的 public 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
Why don't we version models?
模型通常与数据库模式紧密结合。通常,数据库是由 API 的所有版本共享的规范数据存储,因此对模型进行版本化没有多大意义。
此外,在 Rails 应用程序中,大部分业务逻辑通常驻留在模型中。版本控制模型需要复制逻辑或添加另一层抽象,这会引入维护开销。
Is it because we expect our model (underlying database schema) to not change as the API evolves?
没有。数据库架构可以而且确实经常更改。
What happens when I rename a column name in the database and need a new model to account for that?
您没有引入模型来说明架构更改。您调整现有模型以适应更改,然后修改先前 API 的实现,以便先前版本的客户端继续以与之前预期相同的格式获得响应。
由于将您的业务实体(模型)映射到 API 响应,发生在控制器(或序列化器或 json 模板 - 取决于您的首选实现)中 - 您的这些部分必须修改应用程序以确保向后兼容性。
我一直在阅读 REST APIs 版本的所有方法。在几乎所有的实现中,控制器和视图都是版本化的,但模型不是。
以 rails 为例,控制器组织为:
# app/controllers/api/v1/events_controller.rb
class Api::V1::EventsController < Api::ApiController
end
相应的视图也放在不同版本的目录中。我们为什么不版本模型?是因为我们希望我们的模型(底层数据库模式)不会随着 API 的发展而改变吗?当我重命名数据库中的列名并需要一个新模型来解决这个问题时会发生什么?
模型是应用程序内部的一部分,而不是它的 public 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
Why don't we version models?
模型通常与数据库模式紧密结合。通常,数据库是由 API 的所有版本共享的规范数据存储,因此对模型进行版本化没有多大意义。
此外,在 Rails 应用程序中,大部分业务逻辑通常驻留在模型中。版本控制模型需要复制逻辑或添加另一层抽象,这会引入维护开销。
Is it because we expect our model (underlying database schema) to not change as the API evolves?
没有。数据库架构可以而且确实经常更改。
What happens when I rename a column name in the database and need a new model to account for that?
您没有引入模型来说明架构更改。您调整现有模型以适应更改,然后修改先前 API 的实现,以便先前版本的客户端继续以与之前预期相同的格式获得响应。
由于将您的业务实体(模型)映射到 API 响应,发生在控制器(或序列化器或 json 模板 - 取决于您的首选实现)中 - 您的这些部分必须修改应用程序以确保向后兼容性。