【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

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:163422
用户头像

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

关注

评论

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

如何赋能企业数字化转型?华为云有妙招

YG科技

用AI提高代码质量,同事对我的代码赞不绝口~

SoFlu软件机器人

Footprint Analytics 为 ABGA Web3 Gaming Summit 提供支持,助力 Web3 游戏行业发展

Footprint Analytics

议题征集|Flink Forward Asia 2023 正式启动

Apache Flink

flink

Mybatis中传递多个参数的4种方法

源字节1号

开源 软件开发 前端开发 后端开发 小程序开发

关于身心灵学习的感悟1

程序员在修行

INFINI Easysearch 与兆芯完成产品兼容互认证

极限实验室

easysearch 兆芯 国产适配

亚信科技与中国信通院达成全方位、跨领域战略合作

亚信AntDB数据库

AntDB 国产数据库 AntDB数据库

【转载】JVM实际内存占用超过Xmx的原因,设置Xmx的技巧

Geek_b2fe7a

Java

数字化转型与架构-架构设计篇|如何开发一个各部门都满意的系统?

数字随行

数字化转型

数据通信网络之IPv6以太网单臂路由

timerring

数据通信网络

百度智能云千帆社区上线有礼,助力开发者开启大模型之路!

科技热闻

云迁移?是技术问题也是团队问题

在天涯的海角

蓝易云:如何在 Ubuntu 22.04 LTS 上安装分区编辑器 GParted?

百度搜索:蓝易云

云计算 Linux ubuntu 运维 GParted

与中小企业共生共赢,华为云B2B企业节来了

YG科技

从构建者到设计者的低代码之路

树上有只程序猿

软件开发 低代码

Databend 开源周报第 110 期

Databend

使用消息队列有什么优点?有什么缺点?

程序员在修行

ARTS 打卡第四周

程序员在修行

828 B2B企业节,华为云如何提升生态合作伙伴的综合竞争力?

YG科技

一文读懂私有云、公有云和本地化部署

青椒云云电脑

公有云 私有云

Ask Milvus Anything!聊聊被社区反复@的那些事儿 Ⅰ

Zilliz

非结构化数据 Milvus 向量数据库 deepdive

9月24日,线下见个面?

MatrixOrigin

数据库 分布式 MatrixOrigin MatrixOne

从实时监控到智能洞察:Grafana 和 CnosDB 的无限潜力

CnosDB

时序数据库 开源社区 CnosDB

Last Week in Milvus

Zilliz

非结构化数据 Milvus Zilliz 向量数据库

序列化与反序列化一棵树

程序员在修行

英文阅读 The manager's path 1.3

程序员在修行

蓝易云:如何在 RHEL 8 或者 CentOS 8 上安装 MongoDB?

百度搜索:蓝易云

mongodb 云计算 centos 运维 RHEL

不知道该选公有云还是私有云?这些客户请选私有云

青椒云云电脑

桌面云 云桌面

高校云桌面的“正确打开方式”是什么?

青椒云云电脑

云桌面 云桌面方案

代码混淆和加固,保障应用程序的安全性

雪奈椰子

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