2026-08-21 14:58:46.105145+08 / restful-api

HTTP Requests

介绍 RESTful API 中 GET、POST、PUT、PATCH、DELETE 等 HTTP 方法的语义、属性和请求设计实践。

Restful ApiApi DesignOpenapi

HTTP Requests

RESTful API 使用标准 HTTP 方法定义对资源的操作。API 实现必须遵循 HTTP 方法的标准语义,以保证行为可预测、系统互操作性以及客户端与服务端之间的正确协作。

HTTP 方法语义

GET

GET 请求用于获取资源,可以获取单个资源,也可以获取资源集合。

规则:

  • 获取单个资源时,如果资源不存在,应返回 404 Not Found。
  • 获取资源集合时,可以返回 200 OK,表示集合存在但不包含元素;如果集合本身不存在,也可以返回 404 Not Found。
  • GET 请求不得包含请求体。

示例:

http
GET /customers/123

响应:

http
HTTP/1.1 200 OK
json
{
  "id": "123",
  "name": "John Smith"
}

对于资源集合,API 应提供过滤和分页机制。

http
GET /customers?status=active&page=1&pageSize=20

PUT

PUT 请求用于替换完整的资源表示。

其语义是:

使用请求载荷中的表示,替换 URL 所标识的资源。

http
PUT /customers/123

请求:

json
{
  "id": "123",
  "name": "John Smith",
  "status": "active"
}

规则:

  • PUT 通常用于单个资源。
  • 请求载荷表示完整资源。
  • 已有资源数据会被新的表示替换。
  • 对于未知字段,应忽略而不是保存。
  • 成功响应通常返回 200 OK、204 No Content,或者在创建新资源时返回 201 Created。

PUT 与资源创建

虽然 PUT 可以创建资源,但创建顶层资源时通常应优先使用 POST。

使用 PUT 创建资源时:

  • 资源标识符由客户端控制。
  • 重复发送同一个请求必须产生幂等结果。
http
PUT /customers/customer123
PUT /customers/customer123

API 可以结合 ETag 和 If-Match、If-None-Match 等条件 Header,防止并发更新冲突。


POST

POST 请求主要用于在资源集合下创建新资源。

其语义是:

将请求中包含的表示添加到 URL 所标识的资源集合中。

http
POST /customers

请求:

json
{
  "name": "John Smith",
  "status": "active"
}

响应:

http
HTTP/1.1 201 Created
Location: /customers/123
json
{
  "id": "123",
  "name": "John Smith",
  "status": "active"
}

规则:

  • 资源标识符通常由服务端生成。
  • 响应应提供新创建资源的 URI。
  • 常见响应码包括:
    • 201 Created:资源创建成功。
    • 202 Accepted:请求已接受,将进行异步处理。
    • 200 OK:资源已更新或操作已完成。
    • 204 No Content:操作成功,但没有响应体。

与 PUT 不同,重复发送相同的 POST 请求不保证产生相同结果。对于重要场景,API 应考虑让 POST 操作具备幂等性。


PATCH

PATCH 请求用于部分更新已有资源。

其语义是:

根据请求中描述的变更,修改 URL 所标识的资源。

http
PATCH /customers/123

请求:

json
{
  "status": "inactive"
}

更新后的资源:

json
{
  "id": "123",
  "name": "John Smith",
  "status": "inactive"
}

规则:

  • PATCH 通常用于单个资源。
  • PATCH 通常要求资源已经存在。
  • 只更新请求中明确指定的字段。
  • 成功响应通常返回 200 OK 或 204 No Content。

推荐的 PATCH 模式

为了避免实现不一致,一个端点应选择一种更新模式。

1. 条件允许时优先使用 PUT

使用完整资源替换:

http
PUT /customers/123

并提交完整对象。

2. JSON Merge Patch

使用部分对象,并设置:

text
Content-Type: application/merge-patch+json
json
{
  "status": "inactive"
}

3. JSON Patch

使用基于操作的更新,并设置:

text
Content-Type: application/json-patch+json
json
[
  {
    "op": "replace",
    "path": "/status",
    "value": "inactive"
  }
]

4. 特殊操作使用 POST

如果更新行为无法用 PATCH 语义表达,应使用 POST,并清晰记录其行为。


DELETE

DELETE 请求用于删除资源。

其语义是:

删除 URL 所标识的资源。

成功响应可以是:

http
HTTP/1.1 204 No Content

也可以返回 200 OK,并在响应中提供已删除资源的信息。

规则:

  • DELETE 通常用于单个资源。
  • 不建议删除资源集合,因为这意味着删除整个集合。
  • 删除后,后续 GET 请求应返回 404 Not Found 或 410 Gone。
  • 被删除的资源不得继续访问。

HEAD

HEAD 与 GET 具有相同语义,但只返回 HTTP Header,不返回响应体。

http
HEAD /customers/123

典型用途:

  • 检查资源是否存在
  • 检查元数据
  • 验证缓存信息

OPTIONS

OPTIONS 用于发现端点支持的操作。

http
OPTIONS /customers/123

响应:

http
Allow: GET, PUT, DELETE

它也可以描述可用操作或支持的能力。


HTTP 方法属性

HTTP 方法具有三个重要属性:

Safe

Safe 操作不会有意修改服务端状态。

Safe 方法包括 GET、HEAD 和 OPTIONS;POST、PUT、PATCH、DELETE 则不是 Safe 方法。

Idempotent

幂等操作在执行一次或多次时,都应产生相同的预期服务端状态。

方法 幂等
GET 是
HEAD 是
PUT 是
DELETE 是
POST 否
PATCH 不保证

例如,多次执行 PUT /customers/123 应产生相同的资源状态。

Cacheable

响应可以被存储并重复使用。通常可缓存的方法是 GET 和 HEAD。某些 POST 响应在明确规定时也可以缓存。


Query Parameters

查询参数应用于资源过滤和简单查询。

http
GET /customers?name=John

过滤规则应明确:

  • 关联的资源属性
  • 允许的值范围
  • 比较行为
  • 组合规则

示例:

text
name=John
ageGreaterThan=18
createdBefore=2026-01-01

复杂操作

复杂操作应建模为资源,而不是将动词加入 URL。

避免:

http
POST /customers/searchCustomers

推荐:

http
POST /customers/searches

请求:

json
{
  "query": "complex search criteria"
}

响应可以返回新建的搜索资源:

json
{
  "id": "search123",
  "results": {
    "items": []
  }
}

异步处理时,可以返回:

http
HTTP/1.1 202 Accepted
Location: /customers/searches/search123

客户端随后可以查询:

http
GET /customers/searches/search123

异步请求跟踪

当 API 返回 202 Accepted 时,响应应提供跟踪执行状态的方式。

状态示例:

text
queued
pending
processing
cancelled
failed
completed

客户端可以持续轮询:

http
GET /customers/123

直到操作完成。

另一种方式是返回专用的 Job 资源:

json
{
  "job": {
    "id": "456",
    "href": "/jobs/456",
    "status": "processing"
  }
}

然后查询:

http
GET /jobs/456

总结

方法 用途 Safe 幂等
GET 读取资源 是 是
HEAD 读取元数据 是 是
POST 创建资源或执行操作 否 否
PUT 替换资源 否 是
PATCH 部分更新资源 否 不保证
DELETE 删除资源 否 是
OPTIONS 发现支持的能力 是 是

REST API 设计应依赖标准 HTTP 语义,而不是创建自定义的动作式端点。这样可以提升可预测性、互操作性、缓存行为以及 API 的长期演进能力。

HTTP Requests | Remi Resume