写点什么

HTTP API 可演进性最佳实践

  • 2012-02-05
  • 本文字数:1830 字

    阅读完需:约 6 分钟

正如标题所示,Benjamin Carlyle 试图在《Best Practices For HTTP API Evolvability》一文中为围绕 HTTP API 构建的系统的设计定义原则和实践,这些系统是可扩展的,并且能一直进化下去。他先指出了 REST(一种架构风格)和 HTTP API(通过 HTTP 暴露的编程接口)之间的区别。

HTTP API 是针对一个特定服务的面向开发者的接口,也被称为 RESTful 服务契约面向资源架构 URI Space

我说 REST 和 HTTP API 紧密相关是因为大多数 HTTP API 并不严格遵守统一接口约束,严格说来统一接口约束要求接口是“标准的”[…]

文章开头他标识出了 API 设计中的不同元素,这些元素决定了 API 后续的进化。通常来说,API 进化涉及到了设计客户端与服务器的兼容性;特别是 API 的向后和向前兼容变更。 变更频率按增序排列依次是:

  1. API 中用到的方法的通用语义,包含异常条件和其他元数据
  2. API 中用到的媒体类型的通用语义,包含全部 Schema 信息
  3. 构成 API 的 URI 集合,包含 API 中用到的每个通用方法和媒体类型的特定语义

API 进化中改变最少的就是方法的语义。文中描述的最佳实践是识别出向前和向后兼容的变化,运用 Postel 法则让服务与客户端以一种更能容忍的方式进行进化。他建议尽可能地使用 HTTP 错误码来传达兼容性问题。

最佳实践 3:新方法名应该选择那些不会和任何已有方法发生向前兼容的名字。例如,如果要处理的方法必须正确理解(必须理解语义)方法的新特性,那么应该选择一个新的方法名。

最佳实践 4:服务应该忽略它们不理解的标头或组件。代理应该不加修改地传递这些标头,或者是无法理解的组件。

[…]

最佳实践 7:在某个数字范围内为新状态分配一个状态码,这个范围可以粗粒度地标识已存在的条件。

[…]

最佳实践 9:如果新状态是一个已知状态(除了 400 Bad Request 或 500 Internal Server Error)的子集,可以向响应头添加信息来细化已知状态的含义,而不是分配一个新的状态码。

他指出了一个重要的区别,即客户端与服务器交互中媒体类型的对称本质。

[…] 与客户端和服务器之间非对称的方法和状态不同,媒体类型通常能用作请求或响应的负载,即适用于两个方向。为此本节中我们不讨论客户端与服务器,而是讲发送端与接收端。

…这构成了与媒体类型相关的最佳实践的基础

[…]

最佳实践 11:只有当验证逻辑是为与文档发送方相同版本或后续版本的 API 编写的情况下,才可能出现不符合最佳实践 10 的文档验证。

最佳实践 12:在不违反媒体类型设计目标的前提下,如果能向现有媒体类型的 Schema 中添加新信息,那么就添加吧。

他提倡使用 Content-Types 和 Accept 标头来管理发送端与接收端之间的兼容性。

HTTP API 习惯于做出向后不兼容的媒体类型 Schema 变更。新客户端请求或者提供了 Schema 中带有向后不兼容变更的新媒体类型。老的客户端继续请求或提供旧的媒体类型。直到所有重要的相关实现都升级到最新的媒体类型集之前,客户端与服务器端都应该要支持旧的媒体类型。

他认为对资源的修改,尤其是 URI 的修改都是服务器应该关心的事;如果客户端是设计成由超媒体约束驱动的话,一般这些修改都不应该引入兼容性问题。他提倡使用 Cookies 将客户端请求路由到合适的服务实例 / 服务器。

在使用多种通用方法时,我们不再处理通用的方法或媒体类型,而是和带有特定语义的特定 URL 打交道。[…] 在考虑如下服务契约时,我倾向于采用以服务器为中心的视角:

  • GET /invoice/{invoice-id},返回媒体类型 application/invoice+xml,内容是 invoice-id 指定的发货单
  • GET /invoice/{invoice-id}/paid,返回媒体类型 text/plain( xsd:bool 语法),内容是 invoice-id 指定的发货单的支付状态
  • PUT /invoice/{invoice-id}/paid,接受媒体类型 text/plain( xsd:bool 语法),设置 invoice-id 指定的发货单的支付状态

此外,他还提出了一些客户端的最佳实践,以便客户端能应对服务器 URI 的转变(transition)和进化。

最佳实践 19:在升级时,服务应该通过 Cookies 追踪哪些客户端应该连接到旧的服务器,哪些应该连接到新的服务器,或者也可以使用类似的机制。

最佳实践 20:即使不是在响应 HEAD 或 GET 请求,客户端也应该遵从服务器发回的重定向状态响应 [说明: RFC2616 ]

最佳实践 21:重新设计 URL 时,确保新的 URL 拥有和旧 URL 一样的语义,并将旧 URL 重定向到新的 URL 上。

本文中提供了一些基本原理,让 HTTP API 系统能随着时间不断进化。请务必阅读 Benjamin Carlyle 的完整原文以便对这一主题能有更深入的理解。

查看英文原文: Best Practices For HTTP API Evolvability

2012-02-05 09:163522
用户头像

发布了 135 篇内容, 共 60.5 次阅读, 收获喜欢 43 次。

关注

评论

发布
暂无评论
发现更多内容

Trino容错模式深度测评与思考

华为云开发者联盟

大数据 后端 华为云 华为云开发者联盟 交互式分析

数字孪生5G智慧工厂3D可视化云平台

2D3D前端可视化开发

物联网 可视化 数字孪生 智慧工厂 智能制造

用友战略签约广联达,共同使能建筑行业企业高质量发展

用友BIP

建筑行业

Flink测试利器之DataGen初探 | 京东云技术团队

京东科技开发者

大数据 测试 flink sql 执行过程 企业号10月PK榜 DataGen

开放原子开源基金会联合主办的2023 CCF中国开源大会即将开幕

开放原子开源基金会

开源 CCF

负载均衡详解

天翼云开发者社区

负载均衡 服务器

数据如何同步到云服务器

天翼云开发者社区

云计算 数据迁移

战略引领 注重实绩 形成闭环——中国交建绩效管理创新与数智化实践

用友BIP

绩效管理

火山引擎DataTester:跨境电商网站,如何快速实施AB测试 ?

字节跳动数据平台

大数据 A/B 测试 对比实验 数字化增长 企业号10月PK榜

【华秋商城】海量现货库存 闪电发货

华秋电子

连接器

FinClip小程序技术,加速国产化应用新进程

FinClip

校源行丨开放原子开源基金会赴北京信息科技大学走访交流

开放原子开源基金会

云网络对等连接产品的高可用保证

天翼云开发者社区

网络 对等连接

以效率为导向:用ChatGPT和HttpRunner实现敏捷自动化测试(二) | 京东云技术团队

京东科技开发者

自动化测试 敏捷测试 HttpRunner ChatGPT 企业号10月PK榜

可制造性拓展篇│HDI(盲、埋孔)板压合问题

华秋电子

HDI

淘天集团大模型应用十大挑战命题发布

阿里技术

AI 校招 AIGC 淘天

EVE-NG初次启动及WEB客户端访问

小魏写代码

软件测试/测试开发丨Python闭包与装饰器 学习笔记

测试人

Python 程序员 软件测试 自动化测试 测试开发

出版行业企业如何快速实现数智化转型?

用友BIP

Fast by BIP 出版行业

如何强制SQL走性能更优的hash join

华为云开发者联盟

数据库 sql 后端 华为云 华为云开发者联盟

从原理到实战,详解XXE攻击

华为云开发者联盟

安全 后端 华为云 华为云开发者联盟

户外裸眼3D屏幕合适用什么规格

Dylan

3D LED显示屏 户外LED显示屏 led显示屏厂家

当HTAP已成标配,什么才是制胜关键?

MatrixOrigin

分布式数据库 云原生数据库 MatrixOrigin MatrixOne HTAP数据库

使用 GitHub Action 自动更新 Sealos 集群的应用镜像

米开朗基杨

云原生 #go

MySQL的index merge(索引合并)导致数据库死锁分析与解决方案 | 京东云技术团队

京东科技开发者

MySQL 数据库 索引 企业号10月PK榜

HTTP API可演进性最佳实践_REST_Dilip Krishnan_InfoQ精选文章