如何从 0 到 1 搭建十亿级包裹 API Versioning ?

1. Why
1.1 SaaS 产品的特点
SaaS 产品是提供某一领域的解决方案的软件服务,本质是提供订阅服务。
国内大家常用的有飞书、钉钉、企业微信、腾讯会议、百度云、QQ 音乐等基于订阅制的都可以归类为 SaaS,国外常用的 SaaS 有 Google Doc、Zoom、Notion、Slack 等产品。
AfterShip Tracking 属于国际 SaaS 中的 B2B2C 产品,商家订阅 AfterShip 的服务,提供订单信息给我们,我们为商家提供包裹追踪服务,商家可以从我们这获取到物流更新反馈给他们的消费者,也可以通过我们的一体化服务为他们的消费者提供通知等服务。
SaaS 2B 和 2C 的差异
-
产品定位 - 2C 产品通常满足个人消费者的便利和娱乐等日常需求;2B 产品主要是支持企业关键业务流程和运营的重要工具。
-
稳定性影响 - 如果 2C 服务不稳定,会对个人消费者的使用体验造成影响,但不一定会对企业造成损失;如果 2B 服务不稳定,可能会导致业务中断影响到企业的正常运营,造成企业严重的损失。
-
稳定性承诺 - 2C 业务一般企业不会对个人消费者有太多稳定性的承诺;2B 业务在合同中包含 SLA 条款则很常见。 SLA 用于规定服务提供商与客户之间的服务水平标准和责任;通常包含了服务的可用性、响应时间、故障处理和解决时间等关键指标,以确保服务的质量和可靠性。
国内 SaaS 和国际 SaaS 的技术规划的差异
-
专注和极致 - 国际化 SaaS 产品在细节打磨上会有更多的投入,包括对于产品的交付质量有更高的要求,尤其是产品还在早期时候也普遍有较高的质量和标准化。
-
规范和标准 - 体现在如 API 的定义,普遍都是遵循 RESTful API 标准,并且都有相对规范的 API 设计和定义。
-
安全合规 - 在全球范围内,尤其是欧盟、美国和中国在安全隐私要求上都日趋严格,也都有出台了对应的条例:GDPR、CCPA 和《个人信息保护法》。另外对于一家 SaaS 公司来说,当所服务的客户群体有更多是大客户时,对于安全隐私方面的要求也会更高。
-
全球化 - 设计全球化的系统,相比面向单一国家/地区的系统,会需要关注更多的维度。在做系统设计时,系统应该预先设计为支持多国家/地区、多语言、多时区和多币种等。
1.2 API 的重要性
API 也是产品的一部分,而不仅仅是技术。对于 SaaS 产品,提供 API 服务几乎是与企业级用户合作的必需项,特别是在海外。
-
自动化 - 通过 API,企业可以利用 SaaS 产品的功能来构建自动化流程和工作流程。
-
定制化 - 通过 API,企业可以开发自己的应用程序、插件或集成其他工具,以满足特定的业务需求。
-
数据集成 - 通过 API,企业可以灵活地与 SaaS 提供商实现数据的共享和交换。
1.2.1 标准与规范
AfterShip 的 API 严格循序标准与规范,做到极致的细致和严谨,主要包括 RESTful、全球化的架构设计和安全性。
1.2.2 AfterShip API 的演进路线
AfterShip 从十万级发展到到十亿级的包裹追踪,从没有 API 到高标准的 API,不断拔高标准的 API 设计,有力地支撑了业务的增长。
1.3 没有 API Versioned 时面临的挑战
挑战一、变更不规律,打乱客户更新计划
随着 AfterShip 的客户越来越多、品牌越来越大,要求越来越严格,对我们的挑战越来越大。有些客户反馈,原来一个月的通知时间太短了,你们应该提前三个月通知,更有甚者表示没有计划配合我们对已有的 API 进行任何变更。
挑战二、新功能发布缺少调试环境
研发们都知道,在我们对接新的接口协议时,除了对接接口文档一般都有一个测试环境联调的过程。一方面我们要求客户配合变更,虽然我们有提供对接文档,但我们线上只有一个版本的 API,缺乏“测试环境”,用户根本没有办法调试。
2. What
为了解决上述的问题,我们开始学习行业内的知名公司是怎么做的。像 Github, Stripe, Shopify 和 Microsoft 这些公司的 API,都有 API Versioning 的概念。
2.1 本质
很多同学可能以为 URL 上带上 v1, v2, v3 这样的版本号字眼就是 versioning,其实不是。从 2014 年开始我们的 API 就带上了 v4 的版本号,但一直都没有实现 Versioning。
API Versioning 的本质在于
-
API 有版 本概念。
-
同一个 版本的每次 API 变 更都能向后兼容, 向后兼容 - API 的稳定性要求避免破坏性的更改。在进行更新或修改时,应保持对现有功能的支持,以防止影响已部署的应用程序或客户端。
-
不能向后兼容的发布只会发生在新版本中。
怎么评判一个 API 能不能做到向后兼容呢?
我们来看看 Github 关于 API Versioning 的介绍。
所有做 API Versioning 的企业,都会对 breaking changes 有一套自己的规范。不同企业会因为业务形态不同因此对 breaking changes 有不同的定义,有些企业可能比较严格,有些企业可能比较宽松,但大原则是如果变更可能影响到客户端已有的集成即认为该变更是 breaking changes。
只有做到对 API 不发布任何 breaking changes 才能叫向后兼容。
2.2 实现效果
一个非 Versioned 的 API 就像我们刚才提到的,所有功能都在一个版本上迭代,就会遇到我刚才提到的问题。
一个 Versioned 的 API,将提供多套稳定的 API 在线上,每套 API 有独立的逻辑、实例、资源,各版本之间互不影响。客户端可以自由选择调用哪个版本。
举个例子,对于刚才提到的问题,如果用户在使用 2023-10 这个版本,此时我们需要发布新功能,我们新发布的内容只会在 2024-01 的版本发布,完全不会影响到 20 23-10 这个版本。
当新版本发布后,用户在生产环境上可以继续使用 2023-10 的版本,同时他们把 2024-01 这个版本当作他们的“测试环境” 进行联调,实现对他们的业务零 downtime 升级。
3. How
3.1 Support Policy
通过技术调研,我们发现企业新增一个版本都会带来额外的维护成本,所以版本发布频率高的企业,版本支持时间较 短; 版本发布 频率低的企业,版本支持时间较长。 企业可以根据自身的业务特性选择合适的 Support Policy。
AfterShip 的 Support Policy :
1、版本发布周期: 三个月定期发布
2、版本支持时长:十八个月
3.2 API version
版本指定方式如图所示:
业界主 要有通过 request header 和 URL path 两种指定 API version。 我们考虑通过 URL 这种方式更清晰更好维护所有采用这种方式。
3.3 Webhook version
指定版本: 对于 Webh ook 的版本选择有些不同,Webhook URL 由用户提供,在 URL 中指定版本有些不现实。 业界的主要方式是当用户在配置 Webhook URL 的时候需要指定一个版本,后续 webhook 将以指定的版本向该 URL 发送。
确认版本: 通过接收到的 webhook request header 确认,header as-webhook-version 即表示该 webhook 的版本。

3.4 公开文档
文档页面包含所有 live 的版本

3.5 系统架构
3.5.1 Overview

3.5.2 Trade off

3.6 版本维护

4. Takeaway 我们总结了一些经验供各位直接借鉴:
-
API 不仅仅是技术,也是一款产品。如果想要和企业用户合作,API 是必需项。在一开始就应该以高标准、高要求规划我们的 API。
-
API Versioning 的本质是最大化解决向后兼容问题,已存在的 API 不会出现向后不兼容的变更,不能向后兼容的功能只会在新版本中发布。
-
根据我们业务迭代的速度,决定是按固定周期发布版本还是按需发布新版本。比如我们平均每三个月发布一个新功能,可以考虑以 3 个月为周期发布版本,每个版本保留 12 个月,那我们同时最多只需要维护 4 个版本的 API。
-
建议在应用层实现 Versioning,不建议在能力层实现。虽然可以做到非常极致,但是业务复杂后维护成本也是相当可怕。
推荐阅读:
想要了解Go更多内容,欢迎扫描下方👇关注公众号, 回复关键词 [实战群] ,就有机会进群和我们进行交流
分享、在看与点赞Go
