如何管理 API 版本控制背后的逻辑?

How to manage the logic behind the API versioning?

关于后端实现的逻辑,我想确定什么可以被视为 API 的 URI 版本控制的最佳实践。

假设我们有一个 java 应用程序,其中 API:

http://.../api/v1/user
Request:    
    {
      "first name": "John",
      "last name": "Doe"
    }

过了一会儿,我们需要为用户添加 2 个必填字段 API:

http://.../api/v2/user
Request:    
    {
      "first name": "John",
      "last name": "Doe",
      "age": 20,
      "address": "Some address"
    }

我们为每个版本使用单独的 DTO,一个有 2 个字段,另一个有 4 个字段。

我们的应用程序只有一个实体,但我的问题是我们应该如何处理逻辑,作为最佳实践?可以只在一项服务中处理吗?

如果这 2 个新字段 "age" 和 "address" 不是强制性的,则这不会被视为重大更改,但由于它们是,我认为有几个选项:

如果我只对所有用户 API 版本使用一个管理器并在那里放一些 constraints/validations,V2 会工作,但 V1 会抛出异常,因为那些字段不存在。

我知道版本控制是一个很大的话题,但直到现在我在网上找不到具体的答案。 我的直觉告诉我,所有用户 API 版本只有一个管理器将导致一种与干净代码无关的方法,而且,我认为新版本添加的任何更改都必须松散耦合尽可能,因为弃用旧方法并及时删除它们会更容易。

您认为使用 API 进行版本控制是一个有争议的问题,这一点是正确的。 您还进行了重大更改,因此增加 API 的版本是正确的决定 (w.r.t。semver)。

理想情况下,您的后端代码将处于版本控制之下(例如 GitHub)。在这种情况下,您可以放心地将 V1 视为存储库中的 特定提交 。这是已部署并为 V1 提供流量的代码。然后,您可以继续根据需要对代码进行更改。在某些时候,您将添加一些新的重大更改并决定将特定提交标记为 V2。然后,您可以将 V2V1 一起部署。当您决定贬值 V1 时,您可以简单地停止提供流量。

您需要一些方法来确保只有 V1 流量进入 V1 后端,V2 流量进入 V2 后端。通常这是通过使用 Reverse Proxy; popular choices include NGINX and Apache 来完成的。任何足够的反向代理都将允许您根据路径定向请求,如果请求以 /api/v1 为前缀,则将该请求重定向到 Backend1,如果以 /api/v2 为前缀,则重定向到 [=23] =].

希望此模型将有助于保持您的代码整洁:存储库中的 master 分支只需要处理最新的 API。如果你需要对旧的 API 版本进行更改,这可以相对容易地完成:从 V1 提交分支,进行更改,然后将修改后的分支的 HEAD 定义为'new' V1.

针对此答案对您的后端做出了一些您应该注意的假设。首先,您的后端可以水平扩展。例如,这意味着如果您与数据库交互,那么 API 的多个版本都可以同时安全地访问数据库。其次,您拥有部署副本后端的资源。

希望这个解释是有道理的;但如果没有任何问题,请按我的方式发送!

如果您能够 to/can 接受对现有 API 的代码更改,那么您可以直接参考此 link. Also, the link's mentioned at the bottom of the post相应的 GitHub 源代码,如果您想在试错后引入代码更改,这可能会有所帮助。

上述方法(使用@JsonView)基本上可以防止为 same/multiple 客户端引入单个实体的多个 DTO。 最终,也可以避免每次在现有 API.

中引入新字段时引入新版本 APIs

spring-rest-jackson-jsonview
jackson-jsonview