Skip to content

HTTP 方法

IMPORTANT

原文:Learn REST API Design

HTTP 动词(或正式称为方法)构成了我们“统一接口”约束的重要部分,并为基于名词的资源提供了相应的操作(动词)部分。最常用的 HTTP 动词是 POST、GET、PUT、PATCH 和 DELETE,分别对应于创建、读取、更新和删除(即 CRUD)操作。此外,还有一些其他动词,但使用频率较低。在这些不太常用的方法中,OPTIONS 和 HEAD 比其他方法使用得更频繁。

概述

下面是一个总结了主要 HTTP 方法与资源 URI 组合下推荐返回值的表格:

方法CRUD整个集合(例如 /customers)特定项(例如 /customers/{id})
POST创建201(已创建),‘Location’ 头部包含指向 /customers/{id} 的新 ID 链接。404(未找到),409(冲突),如果资源已存在。
GET读取/检索200(OK),客户列表。使用分页、排序和过滤来浏览大型列表。200(OK),单个客户。 404(未找到),如果 ID 未找到或无效。
PUT更新/替换405(方法不允许),除非您想更新/替换整个集合中的每个资源。200(OK)或 204(无内容)。 404(未找到),如果 ID 未找到或无效。
PATCH更新/修改405(方法不允许),除非您要修改整个集合。如果按整个集合进行操作,则是可能的。200(OK)或 204(无内容)。 404(未找到),如果 ID 未找到或无效。
DELETE删除405(方法不允许),除非您想删除整个集合——这通常不希望发生。200(OK)或 204(无内容)。 404(未找到),如果 ID 未找到或无效。

以下是对主要 HTTP 方法的更详细讨论:

POST

POST 动词最常用于创建新资源,尤其是用于创建从属资源,即从属于其他资源(例如父资源)的资源。换句话说,在创建新资源时,POST 请求发送到父资源,服务将负责将新资源与父资源关联,并为其分配一个 ID(新的资源 URI)等。

当创建成功时,返回 HTTP 状态 201,并且返回一个 Location 头部,包含新创建资源的链接,并附带 201 HTTP 状态。

POST 既不是安全的,也不是幂等的。因此,建议将其用于非幂等的资源请求。发送两个相同的 POST 请求,很可能会创建两个包含相同信息的资源。

示例

GET

HTTP GET 方法用于读取(或检索)资源的表示。在正常情况下(或非错误路径中),GET 返回 XML 或 JSON 格式的表示,并附带 HTTP 响应码 200(OK)。在错误情况下,它通常返回 404(NOT FOUND)或 400(BAD REQUEST)。

根据 HTTP 规范的设计,GET(以及 HEAD)请求仅用于读取数据,而不是更改数据。因此,当以这种方式使用时,它们被认为是安全的。也就是说,它们可以在不担心数据修改或损坏的情况下调用——调用一次的效果与调用十次或不调用时是相同的。此外,GET(和 HEAD)是幂等的,这意味着多次发送相同的请求最终会产生与一次请求相同的结果。

不要通过 GET 暴露不安全的操作——它绝不应修改服务器上的任何资源。

示例

PUT

PUT 最常用于更新操作,通过向已知资源的 URI 发送 PUT 请求,并在请求体中包含原始资源的最新表示。

然而,PUT 也可以用来创建资源,前提是资源 ID 由客户端而非服务器选择。换句话说,如果 PUT 请求的 URI 包含一个不存在的资源 ID,此时请求体包含一个资源表示。许多人认为这种方式既复杂又令人困惑,因此,这种创建方法应该尽量少用,甚至不使用。

作为替代,应该使用 POST 来创建新资源,并在请求体的表示中提供客户端定义的 ID,通常是指向不包含资源 ID 的 URI(参见上面的 POST)。

在成功更新时,PUT 返回 200(或如果响应体为空则返回 204)。如果使用 PUT 创建资源,则在成功创建时返回 HTTP 状态码 201。响应体是可选的——返回响应体会消耗更多带宽。如果是创建操作,通常不需要通过 Location 头返回链接,因为客户端已经设置了资源 ID。

PUT 不是安全操作,因为它会修改(或创建)服务器上的状态,但它是幂等的。换句话说,如果你使用 PUT 创建或更新一个资源,然后再次发送相同的请求,资源仍然存在,并且其状态与第一次调用时相同。

例如,如果调用 PUT 请求会使资源中的计数器递增,那么这个调用就不再是幂等的。有时确实会出现这种情况,但足够清晰的文档可以指出此调用不是幂等的。然而,建议保持 PUT 请求幂等性,对于非幂等请求,强烈建议使用 POST。

示例

PATCH

PATCH 用于修改操作。PATCH 请求只需包含对资源的更改,而不是完整的资源。

这类似于 PUT,但请求体包含一组指令,描述当前存储在服务器上的资源应如何修改,以生成新的版本。这意味着 PATCH 请求体不仅仅是资源的部分修改,而是以某种补丁语言(如 JSON Patch 或 XML Patch)描述的。

PATCH 既不是安全操作,也不是幂等的。然而,PATCH 请求可以以幂等的方式发出,这也有助于防止两个 PATCH 请求在相似时间范围内对同一资源的冲突。多个 PATCH 请求之间的冲突可能比 PUT 请求的冲突更危险,因为某些补丁格式需要从已知的基点开始操作,否则可能会破坏资源。使用这种补丁应用的客户端应使用条件请求,以便在资源自客户端上次访问后已更新时,请求失败。例如,客户端可以在 PATCH 请求中使用强 ETag,并在 If-Match 头中提供它。

示例

DELETE

DELETE 很容易理解。它用于删除通过 URI 标识的资源。

在成功删除后,返回 HTTP 状态 200(OK)并附上响应体,可能是已删除项的表示(通常会占用过多带宽),或者是一个包装响应(见下文的返回值)。另一种选择是返回 HTTP 状态 204(NO CONTENT)且无响应体。换句话说,推荐的响应是 204 状态且没有响应体,或者采用 JSEND 风格的响应和 HTTP 状态 200。

从 HTTP 规范角度来看,DELETE 操作是幂等的。如果你删除一个资源,它会被移除。多次调用 DELETE 操作该资源的结果是一样的:资源已被删除。如果调用 DELETE 例如会减少资源中的计数器,那么 DELETE 调用就不再是幂等的。如前所述,使用 POST 来处理非幂等的资源请求是推荐的做法。

然而,关于 DELETE 的幂等性有一个注意事项。第二次调用 DELETE 删除某个资源时,通常会返回 404(NOT FOUND),因为该资源已经被移除,因此不再可查找。对此有一些观点认为 DELETE 操作不再是幂等的,但资源的最终状态是相同的。返回 404 是可以接受的,并准确传达了调用的状态。

示例