第4章:HTTP方法与状态码

在模块边界API契约中,HTTP方法和状态码构成了请求-响应交互的核心语义层。方法定义了动作意图,状态码表达了结果语义;两者共同决定了模块间通信的可预测性与自描述性。本章围绕两种元素展开,重点说明如何在契约设计中正确选用方法、解耦错误传递、保持幂等与安全边界。

4.1 HTTP方法语义对比

方法语义幂等安全(不修改状态)请求体支持典型用途
GET查询 / 读取资源是是无获取列表、详情
POST创建 / 提交处理否否是新增订单、触发动作
PUT全量替换 / 更新是否是更新用户配置、重置状态
DELETE删除资源是否可选注销账户、移除条目
设计原则: 在模块边界处,优先使用幂等方法(GET/PUT/DELETE)以简化重试与补偿逻辑;POST仅用于非幂等操作(如创建、触发异步任务)。方法的选择直接影响了上下游的重试策略和缓存行为。

4.2 状态码分类与语义

状态码按大类分为 2xx 成功、4xx 客户端错误、5xx 服务端错误。在边界契约中,状态码必须精确反映操作结果,避免使用“万能 200”或“万能 500”掩盖业务异常。

范围典型码含义模块契约使用场景
2xx200 OK成功,响应体包含结果GET查询、POST创建成功返回实体
201 Created资源已创建POST新建资源时返回 Location 头
204 No Content成功,无响应体DELETE删除成功、PUT更新成功无需返回
4xx400 Bad Request请求语法错误 / 参数校验失败必填字段缺失、格式错误
401 Unauthorized身份认证失败令牌过期、签名错误
403 Forbidden授权不足权限不足,但有身份
404 Not Found资源不存在ID无效、路由不存在
5xx500 Internal Server Error未预期的服务端错误数据库崩溃、依赖超时
503 Service Unavailable服务临时不可用过载、熔断、维护

避坑提醒: 不要将业务错误(如余额不足)映射为 500;应使用 4xx(如 422 Unprocessable Entity)并附加业务错误码。5xx 只用于服务端内部不可恢复的故障,以便客户端区分重试策略。

4.3 模块边界中的方法与状态数据流

下图展示了一个典型跨模块调用中,方法语义如何触发服务处理,并根据结果返回对应状态码。箭头上的标签表明了幂等性和安全性约束。

HTTP方法与状态码在模块边界数据流中的应用 客户端模块 发起请求 服务端模块 处理业务逻辑 API 网关 GET / PUT / DELETE 200 / 201 / 404 / 503 说明: • GET是幂等的,服务端不会修改状态,应返回200;若资源不存在返回404。 • POST是非幂等的,创建成功返回201 + Location头;失败返回4xx或5xx。 • PUT/DELETE是幂等的,成功返回200/204;重复请求不应产生副作用。 • 5xx状态码应携带错误标识,供客户端实现退避重试。

4.4 契约定义示例(OpenAPI 3.0)

在模块边界契约文档中,每个操作都必须明确声明方法、请求体和响应状态码。以下片段展示了用户管理模块的API定义:

openapi: 3.0.3
info:
  title: 用户模块边界API
  version: 1.0.0
paths:
  /users/{userId}:
    get:
      summary: 查询用户详情
      parameters:
        - name: userId
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: 成功返回用户对象
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          description: 用户不存在
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    delete:
      summary: 删除用户
      responses:
        '204':
          description: 删除成功,无内容
        '404':
          description: 用户不存在
  /users:
    post:
      summary: 创建用户
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserRequest'
      responses:
        '201':
          description: 创建成功,返回用户对象
          headers:
            Location:
              schema: { type: string }
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '422':
          description: 请求参数校验失败
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'

4.5 状态码与错误码的协同策略

单个状态码不足以描述所有业务异常,需配合业务错误码实现细粒度原因传递。推荐规范:

  • HTTP头中通过 X-Error-Code 或响应体内 code 字段返回模块级错误标识;
  • 4xx 状态码 + 业务错误码 → 客户端可针对不同错误码执行不同处理(如重新授权、修正参数);
  • 5xx 状态码 + 全局重试标识 → 客户端使用固定退避策略;
  • 避免在 2xx 响应体中嵌入错误信息(违反语义化原则)。

契约固化建议: 在模块边界合约中,明确列出每个方法支持的 至少一个成功状态码 和 至少一个错误状态码;禁止声明“default”响应而不给出具体码值。通过代码生成(如 openapi-generator)自动校验状态码覆盖度。

4.6 本章小结