如何管理 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 版本的业务层中只使用一个 manager/service (但是代码的复杂性在只有一个管理器的情况下会随着时间的推移而增长很多并且难以维护)
- 所有用户 API 版本只使用一个管理器,并且还使用 class 作为翻译器,这样我就可以使旧 API 版本与新版本兼容
- 业务层中每个用户的新 manager/service API 版本
如果我只对所有用户 API 版本使用一个管理器并在那里放一些 constraints/validations,V2 会工作,但 V1 会抛出异常,因为那些字段不存在。
我知道版本控制是一个很大的话题,但直到现在我在网上找不到具体的答案。
我的直觉告诉我,所有用户 API 版本只有一个管理器将导致一种与干净代码无关的方法,而且,我认为新版本添加的任何更改都必须松散耦合尽可能,因为弃用旧方法并及时删除它们会更容易。
您认为使用 API 进行版本控制是一个有争议的问题,这一点是正确的。
您还进行了重大更改,因此增加 API 的版本是正确的决定 (w.r.t。semver)。
理想情况下,您的后端代码将处于版本控制之下(例如 GitHub)。在这种情况下,您可以放心地将 V1
视为存储库中的 特定提交 。这是已部署并为 V1
提供流量的代码。然后,您可以继续根据需要对代码进行更改。在某些时候,您将添加一些新的重大更改并决定将特定提交标记为 V2
。然后,您可以将 V2
与 V1
一起部署。当您决定贬值 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
关于后端实现的逻辑,我想确定什么可以被视为 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 版本的业务层中只使用一个 manager/service (但是代码的复杂性在只有一个管理器的情况下会随着时间的推移而增长很多并且难以维护)
- 所有用户 API 版本只使用一个管理器,并且还使用 class 作为翻译器,这样我就可以使旧 API 版本与新版本兼容
- 业务层中每个用户的新 manager/service API 版本
如果我只对所有用户 API 版本使用一个管理器并在那里放一些 constraints/validations,V2 会工作,但 V1 会抛出异常,因为那些字段不存在。
我知道版本控制是一个很大的话题,但直到现在我在网上找不到具体的答案。 我的直觉告诉我,所有用户 API 版本只有一个管理器将导致一种与干净代码无关的方法,而且,我认为新版本添加的任何更改都必须松散耦合尽可能,因为弃用旧方法并及时删除它们会更容易。
您认为使用 API 进行版本控制是一个有争议的问题,这一点是正确的。 您还进行了重大更改,因此增加 API 的版本是正确的决定 (w.r.t。semver)。
理想情况下,您的后端代码将处于版本控制之下(例如 GitHub)。在这种情况下,您可以放心地将 V1
视为存储库中的 特定提交 。这是已部署并为 V1
提供流量的代码。然后,您可以继续根据需要对代码进行更改。在某些时候,您将添加一些新的重大更改并决定将特定提交标记为 V2
。然后,您可以将 V2
与 V1
一起部署。当您决定贬值 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