Logo
Section 1 / 8

理解 Web API 协议、实践与风格

了解 Web API 协议、实践与设计风格。

导入

理解 Web API 协议、实践与风格

了解 Web API 协议、实践与设计风格。

  • HTTP 协议
  • Web 成功背后的通用实践
  • 用于设计和构建基于 HTTP 应用的 REST 风格
...

HTTP 是一项开放标准协议,近 30 年来为 Web 的稳定和发展提供了强大支持。虽然 HTTP 并非互联网上用于构建 API 的唯一开放协议,但至今它仍是最广泛使用的协议,我们的所有 API 都将基于它构建。

Web 本身实际上并不是一个标准,而更像是一组通用模式和实践,最初由蒂姆·伯纳斯-李(Tim Berners-Lee)在 1989 年首次实现早期版本的 HTTP 和 HTML 时确立。我们的 API 也将遵循这些原则。

最后,罗伊·T·菲尔丁(Roy T. Fielding)提出的在 HTTP 上构建应用的 REST 风格,甚至比标准或通用实践更为宽泛。REST 实际上是一种行为风格,菲尔丁将其系统化地记录下来,旨在帮助软件架构师和程序员构建健壮、可靠且可扩展的应用程序和 API。在设计和实现我们的 API 时,将主要依据菲尔丁的指导原则。

HTTP 基础

Web 上大多数 API 都依赖一种标准协议,以确保机器能够通过互联网相互通信。这种协议就是超文本传输协议(HTTP)。HTTP 的第一个公开版本发布于 1991 年,此后近 30 年间又陆续发布了多个版本。目前,HTTP 协议标准由互联网工程任务组(IETF)负责维护。

...
HTTP 协议基础

我们不会花太多时间详细讲解 HTTP,但会介绍一些基本概念。理解 HTTP 的工作原理以及每次通过互联网发送的 HTTP 消息的组成部分,对于设计和构建依赖该协议的 API 非常有帮助。

...
HTTP 的一些基础知识

我们将涵盖以下内容:

  • HTTP 消息:HTTP 为所有请求和响应定义了统一的文本消息格式。
  • HTTP 方法:为了确保发送方和接收方能相互理解,HTTP 定义了一组方法名称,在实现 API 时我们必须处理这些方法。
  • 其他 HTTP 特性:还有一些其他方面的特性值得一提,有助于大家更高效地使用 HTTP。

HTTP 消息

了解 HTTP 协议最重要的一点是:它的设计完全基于“传递消息”的理念,而非传递对象或数据库查询结果。这种以消息为中心的设计正是 HTTP(以及 HTML)能够迅速普及并广泛应用的原因之一。只要我们能编写出可以处理 HTTP 消息的客户端或服务端程序,就可以搭建 HTTP 服务器并提供内容,而不受编程语言、对象模型或数据库类型的限制。

那么,一个 HTTP 消息长什么样呢?其实非常简单。每个 HTTP 请求或响应消息都包含三个部分:

  • 起始行(Start-line)
  • 头部集合(Header Collection)
  • 消息体(Message Body)

下面是一个真实的 HTTP 请求和响应示例:

1POST /create-user HTTP/2 2Host: www.example.com 3Content-Type: application/x-www-form-urlencoded 4Content-Length: 46 5 6name=mike&email=mike@example.org&sms=123456789

第 1 行是起始行,包含三个元素:

  • HTTP 方法(POST)
  • URL(/create-user)
  • 协议版本(HTTP/2)

第 2 行到第 4 行属于头部集合。本例中包含三个字段:

  • 主机名(Host: www.example.com)
  • 发送的消息体类型(Content-Type: application/x-www-form-urlencoded)
  • 消息体大小(Content-Length: 46)

头部集合以空行结束,随后是消息体。此处的消息体是一组键值对,服务器将用它们创建一个新的用户记录。

HTTP 服务器接收请求(如上所示),并返回响应。以下是服务器收到上述请求后可能返回的一个响应示例:

1HTTP/2 201 Created 2Date: Mon, 27 Jul 2020 12:28:53 GMT 3Content-Length: 0

在这个响应中,第 1 行包含三个略有不同的部分:

  • HTTP 版本(HTTP/2)
  • 状态码(201)
  • 状态消息(Created)

第 2 行和第 3 行包含两个头部字段:响应发送的日期(格林尼治标准时间,GMT)和消息体长度。可以看到 Content-Length 被设为 0,表示此响应没有消息体。在 HTTP 中,消息体是一个可选部分,请求或响应常常不包含消息体。

以上就是理解 HTTP 消息所需掌握的核心内容。尽管存在许多例外情况和额外细节,但在此我们无需深入探讨。

HTTP 方法

HTTP 的另一个重要特性是在请求开头使用“方法”,使客户端(发起请求的一方)能够告知服务器(接收请求的一方)希望执行何种操作。

...
HTTP 方法

CRUD 方法:许多人以关系型数据库的方式使用四个基本 HTTP 方法(POST、GET、PUT、DELETE)。在这种方式下,POST 用于创建新记录,GET 用于读取已有记录,PUT 用于更新已有记录,DELETE 用于删除已有记录。这四个方法有时被称为 CRUD 方法(对应创建、读取、更新、删除)。然而,这种数据库导向的理解方式并非 HTTP 规范制定者最初设想的使用方式,因此我们不会采用“CRUD”这一术语。

...
HTTP 方法及其说明

虽然这些关键字被称为 HTTP 方法,但它们并不像程序员通常理解的“方法”那样运作——它们不是服务器调用的函数或过程。它们只是规范中的关键字,用于帮助客户端和服务器明确请求的意图。由于 HTTP 标准的结构设计允许随时添加新的关键字,例如 PATCH 关键字于 2010 年被标准化,过去也曾使用过其他关键字。在本课程中,我们将主要使用最常用的四个 HTTP 方法(GET、PUT、POST、DELETE),但也应了解还有其他方法存在。

安全性与幂等性

HTTP 方法关键字体现了客户端与服务器之间的一种约定,其中包括“安全请求”和“幂等请求”的定义。

安全请求是指不会对现有数据造成实质性更改的请求。例如,HTTP 的 GET 请求被定义为安全的,因为 GET 本质上只是一种读取操作。相反,HTTP 的 DELETE 请求则被定义为不安全的,因为它会导致数据被移除或删除。

除了安全性之外,HTTP 方法还具有幂等性(idempotence)的特性。幂等请求意味着无论重复执行多少次,结果都保持一致。例如,如果我们使用 DELETE 方法请求删除服务器上的第 21 号记录,无论发送一次还是 100 次该请求,最终结果都相同——系统中只会删除第 21 号记录。

尽管 POST 方法被广泛使用,但它不是幂等的。这意味着如果使用 POST 向系统添加一条新记录,并多次执行该请求,就会导致多条记录被创建。有时这正是我们期望的行为,但更多时候我们只希望创建一条记录。这正是使用 HTTP POST 方法时可能遇到的问题。

...
HTTP 方法的工作机制

试想这样一个场景:我们使用 HTTP POST 请求向银行服务发送指令,要求将 200 美元从账户 A 转到账户 B,但始终未收到响应。此时该怎么办?是否应该再次发送相同的请求?

在这种情况下,我们无法确定发生了什么:可能是请求根本未到达服务器(即转账未发生),也可能是请求已成功执行,只是确认成功的响应未能送达我们。如果是前者,我们可以重新发送请求;如果是后者,则不应重发。但我们很难判断具体属于哪种情况。

然而,如果我们使用的是 HTTP PUT 请求(一种幂等方法),就可以放心地重复发送请求,而不必担心导致资金被多次转账。

简介

Web 与 REST API