RESTful API 是现在互联网应用开发中最常用的接口规范之一。对于一个长期发展的系统来说,API 的升级是不可避免的。但是,每个版本的接口间可能存在较大的差异,开发人员必须确保新版本的 API 不会破坏旧版本的兼容性。这篇文章主要介绍如何保持 API 的版本兼容性,让不同版本的 API 能够和谐共存。
版本的概念
在开始介绍如何保持 API 版本的兼容性之前,让我们先了解一下版本的概念。
版本号通常是由三个数字组成,以点号分隔。例如,1.2.3。其中,第一个数字代表大版本号,表示重大变更或不兼容的改动;第二个数字代表小版本号,表示向后兼容的功能新增或修改,但不破坏原有功能;第三个数字代表修订号,表示修复 bug 或其他小改动。
例如,API 的初始版本可以是 1.0.0,然后,通过对 API 进行改进和修复,可以升级到 1.0.1、1.1.0、1.1.1 等其他版本。重大变更引起不兼容的改动,只有在下一个大版本号中才会出现。因此,对大版本号的更新应该是谨慎的,并且应该尽量延迟更新。小版本号和修订号的升级则可以更频密一些。
兼容性问题
API 的升级可能引起兼容性问题,例如:
- 参数变更:请求参数的名称、类型或格式的改变。
- 接口变更:接口的命名或执行逻辑的改变。
- 错误处理:错误码或错误信息的修改。
- 数据格式:返回数据的格式或内容的变更。
这些变化可能导致旧版本的客户端(如 Web 应用程序或手机应用程序)无法使用新的 API。因此,一个好的 API 设计必须遵循以下原则:
- 向后兼容:不破坏原有功能,新的 API 版本应该向后兼容旧版本。
- 明确版本号:所有 API 请求都应该指定版本号,客户端应该使用相应版本的 API 调用。
- 客户端提示:如果有可用的更新版本,API 应该向客户端提供提示信息。
方案和实践
版本标记
为了确保版本兼容性,为每一个 API 签订合同并确定版本。版本可以以各种方式标记。最常见的方式是在 URL 后面加上版本号,如:
https://api.example.com/v1/products/
这种方式的好处是明确,提高了可读性。同时,如果你需提供两个版本,你需要创建不同的 URL,如:https://api.example.com/v1/products/ 和 https://api.example.com/v2/products/。对于复杂的 API,可能需要传递更多参数才能确定正确的 API 版本。
参数的变更
当参数的名称,类型或格式发生变化时,需要保证新版本 API 向后兼容旧版本。例如,假设你的 API 先前的 URL 是这样的:
https://api.example.com/v1/products?number=5
如果你要将参数“number”更改为“qty”,请保证你的客户端可以识别旧版和新版的 API。
https://api.example.com/v1/products?number=5(旧版) https://api.example.com/v1/products?qty=5(新版)
接口变更
当你要升级你的 API接口、更改功能或添加一个新路径时,不应该破坏任何现有API。如果你不得不修改所有API,但不可避免的有不兼容的更改。在这种情况下,所做的更改应当明确标记,并尽可能减少对现有用户的影响。此外,需要向旧版本的用户提供一个新的方法。例如,通过添加一条语句在请求头中提供警告:
Warning: This API will be deprecated soon. Please switch to the new version.
异常处理
如果你决定修改你的 API 的错误码或错误消息,你必须保持新的 API 版本兼容老版本的 API。否则,客户端可能无法正确处理错误并产生混乱。一种简单的解决方案是,让新 API 返回与旧 API 相同的错误码,但在错误信息中提供新消息。
数据格式
如果你的 API 返回的数据已被修改,客户端可能会产生冲突。例如,如果一个 API 先前返回 XML,后来更改为 JSON,则需要确定可以识别两种格式的正常用户。 在此示例中,当出现此问题时,所做的最好的更改是将这个改动作为一个大版本进行发布。
总结
在这篇文章中,我们讨论了保持 RESTful API 版本兼容性的最佳实践。
- 明确版本号:确定 API 的版本,通过标记版本号在 URL 或其他方式传递给客户端。
- 向后兼容:确保升级不会破坏旧版本的客户端。
- 给出提示:为客户端提供 API 的变更提示信息。
- 可能的冲突:尽可能减少对现有用户的影响。
上述最佳实践可以确保 API 的版本兼容性,并最终使你的 API 更加健壮和可靠。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651849d295b1f8cacd0b4674