是否有实现 API 版本控制的最佳实践?我对以下几点感兴趣:
- Controller 、服务 - 例如我们是否为每个版本的 API 使用不同的 Controller 类?新的 Controller 类是否继承旧的 Controller ?
- 模型 - 如果 API 版本包含同一模型的不同版本 - 我们如何处理转换?例如。如果 API 的 v1 使用模型的 v1,并且 API 的 v2 使用模型的 v2,并且我们希望同时支持两者(为了向后兼容) - 我们如何进行转换?
- 我可以在 Java 和 JavaScript 中使用现有的框架/库来实现这些目的吗?
谢谢!
最佳答案
- 我总是建议每个 API 版本使用不同的 Controller 类。它让维护人员保持干净和清晰。通常可以通过复制并粘贴上一个版本来启动下一个版本。您应该定义明确的版本控制策略;例如N-2 版本。通过这样做,您最终会得到 3 个并行的实现,而不是某些人认为的爆炸式实现。在 Controller 之外重构业务逻辑和其他不特定于 HTTP API 版本的组件有助于减少代码重复。
- 我强烈认为,除了具有版本中立功能(但不包括 API)的基本 Controller 外, Controller 绝对不从另一个 Controller 继承。 HTTP 是 API。 HTTP 有方法,而不是动词。将其视为
Http.get()
。使用另一种语言(例如 Java、C# 等)是与 HTTP 阻抗不匹配的外观。 HTTP 不支持继承,因此尝试在实现中使用继承只会加剧不匹配问题。还有其他实际挑战。例如,您可以取消继承一个方法,这会使在继承的 Controller 中取消 API 的问题变得复杂(并非所有版本都是附加的)。调试也可能会令人困惑,因为您必须找到正确的实现来设置断点。根据我的经验,对版本控制策略和其他组件的责任进行一些思考,但会否定继承的需要。 - 模型转换是一个实现细节。这完全取决于服务器。支持转换是非常具体的。转换可以是双向 (
v1<->v2
) 或单向 (v2->v1
)。 Mapper 是将一种形式转换为另一种形式的一种相当常见的方法。附加属性场景通常只需要旧 API 版本存储中的新属性的默认值。最终,这个问题没有适用于所有场景的单一答案。 - 应该注意的是,向后兼容性在 HTTP 中是一个误称。确实没有这样的事情。 API版本是包含模型的合约。新版本模型与旧版本模型之间的转换的便利性或容易性应该被认为是便利性。人们很容易认为附加更改是向后支持的,但服务器不能保证它与客户端一样。在 HTTP 上下文中强调向后支持的概念将帮助您落入成功的深渊。
- 使用 Open API(以前称为 Swagger)可能是将客户端与任何语言集成的最佳选择。有一些工具可以使用该文档将客户端创建为您首选的编程语言。我对服务器端的 Java 库/框架没有具体的建议,但有多种选择。
关于backwards-compatibility - 支持不同REST API版本的多个版本模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67313792/