HTTP 方法语义与状态码选择:GET/POST/PUT/DELETE/PATCH、2xx/3xx/4xx/5xx 使用场景

RESTful API 的核心是“资源”与“动作”。HTTP 方法(Method)表达对资源执行的操作语义,状态码(Status Code)说明操作结果。方法选错、状态码返回混乱,会导致客户端无法正确解析接口意图,甚至引发幂等性问题或安全漏洞。本章从方法语义、状态码分类、选型决策三个维度展开,配合流程图与代码示例,帮助你在支付 SDK 对接场景中做出正确选择。

2.1 HTTP 方法语义对比

REST 规范将 CRUD(Create、Read、Update、Delete)映射为 POST、GET、PUT、DELETE、PATCH。支付 SDK 中常见的账户查询、订单创建、退款、部分修改等操作,方法选择必须遵循幂等性和安全属性。

方法语义幂等安全请求体响应状态码支付场景示例
GET获取资源✅✅(无副作用)无200 OK查询订单状态、余额
POST创建资源(或触发动作)❌❌有201 Created创建支付订单、发起退款
PUT全量替换资源✅❌有200 OK / 204 No Content更新支付配置(全量)
DELETE删除资源✅❌可选200 OK / 204 No Content删除无效的支付渠道
PATCH部分修改资源❌(需设计)❌有200 OK更新订单备注、修改支付金额

要点:GET 和 DELETE 必须保证幂等;POST 不可幂等,重试会导致重复创建,支付 SDK 中需配合幂等键(Idempotency-Key)使用;PATCH 的幂等性依赖于字段定义,建议采用 JSON Patch 规范。

2.2 状态码分类与使用场景

HTTP 状态码以首位数字划分大类。在 API 设计中,明确每种状态码的含义有助于客户端做自动重试、降级或提示用户。

分类码段含义支付 SDK 典型场景
2xx 成功200, 201, 204请求已成功被服务器接收、理解并接受200 查询成功、201 订单创建成功、204 删除成功
3xx 重定向301, 302, 307, 308资源位置发生变化,需客户端重新请求支付收银台跳转(302)、资源迁移(301)
4xx 客户端错误400, 401, 403, 404, 409, 422请求格式错误、认证失败、资源不存在或冲突400 参数校验失败、401 过期、404 订单不存在、409 重复支付
5xx 服务端错误500, 502, 503, 504服务器内部错误或不可用500 支付网关异常、503 维护中、504 上游超时

避坑提醒:不要将业务错误(如余额不足)一律返回 500;应返回 4xx 并附带具体错误码和 message,便于客户端精确定位问题。支付 SDK 对接中,3xx 通常用于跳转支付网关,客户端需自动跟随(或弹出浏览器),不可直接解析响应体。

2.3 方法+状态码选择决策流程

下图展示了从客户端请求到最终响应的决策路径。每个分支代表方法语义和业务逻辑共同决定的状态码。

HTTP 方法语义与状态码选择决策流程图 客户端请求 HTTP 方法 GET POST PUT DELETE PATCH 资源存在? 200 + 资源数据 404 Not Found 校验通过? 201 Created 422 Unprocessable 资源存在 200 或 204 201 Created 删除成功 204 No Content 404 Not Found 合并成功 200 + 资源 422 或 409 3xx 重定向未在图中展开:支付跳转通常返回 302 Location,客户端需自动跟随;缓存场景使用 304 Not Modified。 5xx 服务端错误:应在所有逻辑异常后统一返回 500/503,避免泄露内部细节。

2.4 代码实战:方法与状态码的对应

以下示例展示一个支付订单 API 的完整请求-响应流程(基于 JSON 格式)。客户端使用 curl 测试,注意方法选择与返回状态码的对应关系。

# 1. 创建订单 (POST) → 201 Created
curl -X POST https://api.pay.example.com/orders \
  -H "Content-Type: application/json" \
  -d '{"amount": 100, "currency": "CNY", "description": "测试订单"}'
# 响应:
# 201 Created
# {"id": "order_123", "status": "pending", "amount": 100, ...}

# 2. 查询订单 (GET) → 200 OK
curl -X GET https://api.pay.example.com/orders/order_123
# 响应:
# 200 OK
# {"id": "order_123", "status": "paid", "amount": 100, ...}

# 3. 部分修改订单 (PATCH) → 200 OK
curl -X PATCH https://api.pay.example.com/orders/order_123 \
  -H "Content-Type: application/json-patch+json" \
  -d '[{"op": "replace", "path": "/description", "value": "已修改备注"} ]'
# 响应:
# 200 OK
# {"id": "order_123", "description": "已修改备注", ...}

# 4. 删除订单 (DELETE) → 204 No Content
curl -X DELETE https://api.pay.example.com/orders/order_123
# 响应:
# 204 No Content (无响应体)

# 5. 重复创建 (POST 幂等缺失) → 409 Conflict
curl -X POST https://api.pay.example.com/orders \
  -d '{"amount": 100, "idempotency_key": "key-001"}'
# 第二次请求时:
# 409 Conflict
# {"error": "duplicate_order", "message": "订单已存在"}

调试建议:使用 curl -v 查看完整请求/响应行和状态码;支付 SDK 对接中务必检查状态码首位数字,不要仅判断 200。例如 302 跳转需自动跟随(curl 默认开启 -L),204 无内容需要特殊处理。

2.5 常见错误与选型陷阱

  1. 误用 POST 做查询:长参数查询使用 GET + query string,POST 查询会破坏缓存机制且不幂等。
  2. PUT 部分更新:PUT 要求全量替换,部分更新必须用 PATCH,否则导致字段丢失。
  3. 所有成功都返回 200:创建资源应返回 201,删除应返回 204,否则客户端无法区分操作类型。
  4. 业务异常返回 500:余额不足、冻结等应返回 422(Unprocessable Entity)并附带业务错误码。
  5. 忽略 3xx 重定向:支付收银台跳转依赖 302,客户端若不跟随将无法完成支付流程。

安全提示:4xx 响应的响应体不应泄露敏感信息(如 SQL 错误、堆栈跟踪)。支付 SDK 对接时,注意 401(Unauthorized)和 403(Forbidden)的区别:前者表示未认证,后者表示无权限,需在文档中明确给出处理方式。