2. REST API 基础回顾:HTTP 协议核心概念、RESTful 设计原则、常见 HTTP 方法与状态码

在进入契约压测之前,必须牢固掌握 REST API 的底层通信协议与设计规范。本章将系统梳理 HTTP 协议的核心要素、RESTful 架构的设计原则、常用 HTTP 方法的语义与幂等性,以及状态码与响应格式的最佳实践。这些知识是后续编写压测脚本、验证接口契约、分析性能数据的基石。

2.1 HTTP 协议核心概念

HTTP(HyperText Transfer Protocol)是 REST API 的传输载体。理解其请求-响应模型、无状态特性与报文结构,是正确构造压测请求的前提。

概念 说明 压测关注点
请求-响应模型 客户端发起请求,服务端返回响应,一次交互完成。 压测需模拟大量并发请求,关注响应时间与吞吐量。
无状态 服务端不保存客户端上下文,每个请求独立处理。 压测脚本需在每次请求中携带完整认证/会话信息。
URL + 方法 统一资源定位符 + 操作动词,唯一标识资源与动作。 压测需精确构造 URL 与 HTTP 方法组合。
Header 携带元数据:Content-Type、Authorization、Cache-Control 等。 压测需模拟真实 Header,避免被限流或拒绝。
Body 请求/响应载荷,通常为 JSON/XML 格式。 压测需生成合法 Body,并验证响应 Body 结构。
压测提示: 在 Go 中使用 net/http/httptest 或 vegeta 等工具时,务必显式设置 Content-Type: application/json 与 Accept: application/json,否则服务端可能返回 415 或 406 状态码。

2.2 RESTful 设计原则

REST(Representational State Transfer)是一种架构风格,而非协议。遵循 RESTful 原则的 API 更易于理解、测试与维护。以下是六大核心原则:

  1. 资源导向: 每个 URL 代表一个资源(如 /users、/orders/123),而非操作。
  2. 统一接口: 使用标准 HTTP 方法(GET/POST/PUT/DELETE)操作资源。
  3. 无状态通信: 每个请求包含所有必要信息,服务端不存储会话状态。
  4. 可缓存: 响应应明确标记是否可缓存,提升性能。
  5. 分层系统: 客户端无需关心中间层(网关、负载均衡器)的存在。
  6. 按需代码(可选): 服务端可返回可执行脚本(如 JavaScript),但 REST API 中较少使用。
契约压测视角: 压测脚本应严格遵循 RESTful 原则——使用正确的 HTTP 方法、在 URL 中传递资源 ID、在 Body 中传递资源属性。违反原则的请求(如用 GET 修改资源)会被服务端拒绝,导致压测结果失真。
RESTful 架构交互流程 客户端 网关 / 负载均衡 REST 服务 数据库 GET /users 转发请求 查询 结果 200 OK + JSON 响应 RESTful 架构:无状态、统一接口、资源导向,压测时需模拟完整请求链路

2.3 常见 HTTP 方法:语义、幂等性与安全性

REST API 通过 HTTP 方法表达对资源的操作意图。压测时必须严格遵循方法的语义,否则服务端可能返回 405 Method Not Allowed 或产生非预期副作用。

方法 语义 幂等 安全 请求 Body 响应 Body
GET 获取资源 是 是 无 资源表示
POST 创建资源 否 否 资源属性 新资源 ID / 完整资源
PUT 全量更新资源 是 否 完整资源 更新后的资源
DELETE 删除资源 是 否 无 空 / 确认消息
PATCH 部分更新资源 否 否 差异字段 更新后的资源
幂等性陷阱: 压测中若重复发送 POST 请求,可能创建多条重复资源,导致数据污染。建议在压测前清理测试数据,或使用幂等键(Idempotency-Key)保证 POST 的幂等性。

2.4 状态码与响应格式

HTTP 状态码是服务端对请求处理结果的标准化反馈。压测脚本需要根据状态码判断请求是否成功,并提取响应数据进行验证。

2.4.1 常见状态码分类

分类 范围 典型状态码 含义
1xx 信息 100-199 100 Continue 请求已接收,继续发送 Body
2xx 成功 200-299 200 OK、201 Created、204 No Content 请求成功处理
3xx 重定向 300-399 301 Moved Permanently、302 Found 资源位置变更,需重定向
4xx 客户端错误 400-499 400 Bad Request、401 Unauthorized、404 Not Found、429 Too Many Requests 请求格式/权限/资源问题
5xx 服务端错误 500-599 500 Internal Server Error、502 Bad Gateway、503 Service Unavailable 服务端异常或过载

2.4.2 响应格式最佳实践

REST API 通常使用 JSON 作为响应格式。一个规范的响应应包含以下结构:

{
  "code": 200,
  "message": "success",
  "data": {
    "id": 123,
    "name": "张三",
    "email": "zhangsan@example.com"
  },
  "timestamp": "2025-01-15T10:30:00Z"
}

压测脚本需要解析响应 JSON,提取 code 字段判断业务成功与否,并从 data 中提取关键字段进行断言。

契约验证要点: 压测不仅要检查 HTTP 状态码,还要验证响应 Body 的字段类型、取值范围与嵌套结构。例如,id 必须为整数且大于 0,email 必须符合邮箱格式。这些验证逻辑应在压测脚本中实现,确保接口契约不被破坏。
HTTP 状态码决策流程 发起 HTTP 请求 服务端处理请求 成功? 是 2xx 成功响应 否 4xx 客户端错误 5xx 服务端错误 压测中需区分 4xx(客户端问题)与 5xx(服务端问题),分别采取不同的处理策略

2.5 本章小结

本章回顾了 HTTP 协议的核心概念、RESTful 设计原则、常见 HTTP 方法的语义与幂等性,以及状态码与响应格式的规范。这些基础知识是后续章节编写 Go 压测脚本、设计测试用例、分析性能数据的理论支撑。在进入实战之前,请确保你能够:

  • 准确区分 GET/POST/PUT/DELETE 的语义与幂等性差异。
  • 根据状态码快速判断请求结果,并提取响应数据进行契约验证。
  • 理解 RESTful 原则对压测脚本设计的影响(如无状态、资源导向)。
下一步: 第 3 章将介绍 Go 语言中常用的 HTTP 客户端库(net/http、resty、gentleman),并对比它们在压测场景下的性能与易用性。