跳到主要内容

API 设计与 HTTP 实践

后端对外(或对内)的第一界面是 API。面试很少考「REST 定义背全文」,更多考:资源怎么建模、HTTP 语义怎么用、幂等与错误怎么设计。

REST 直觉​

原则做法
资源用名词/users、/orders/{id},动词放 HTTP 方法
方法表语义GET 读、POST 建、PUT/PATCH 改、DELETE 删
状态码表结果2xx 成功、4xx 客户端、5xx 服务端
无状态服务端不存会话上下文在「连接」里(鉴权 token 除外)
GET /api/v1/orders?status=paid&page=2
POST /api/v1/orders
PATCH /api/v1/orders/42 { "status": "shipped" }
DELETE /api/v1/orders/42

HTTP 状态码(常用)​

码何时用
200GET/PATCH 成功
201POST 创建成功
204DELETE 成功无 body
400参数非法
401未认证
403已认证无权限
404资源不存在
409冲突(重复创建、版本冲突)
429限流
500未预期服务端错误

别全 200 + body 里 code——网关、监控、客户端库都依赖真实状态码。

版本与兼容​

策略说明
URL 版本/v1/users — 最直观
HeaderAccept: application/vnd.xxx.v2+json
字段扩展新增可选字段;删/改语义要新版本

破坏性变更:新版本 + deprecate 旧版 + 文档与下线时间。

分页​

方式优缺点
Offset?page=2&size=20;深页慢(DB OFFSET)
Cursor / Keyset?after=id123&limit=20;稳定、适合 Feed
时间游标按 created_at + id tie-break

对外 API 推荐 cursor;管理后台可用 offset。

幂等​

场景做法
GET / PUT / DELETE天然幂等(语义上)
POST 创建Idempotency-Key 请求头 + 服务端去重表
支付 / 下单业务唯一键 + DB 唯一约束

重复请求应返回同一结果,而不是重复扣款。

错误体​

{
"error": {
"code": "ORDER_NOT_FOUND",
"message": "订单不存在",
"request_id": "req-abc-123"
}
}
字段作用
code机器可读,客户端分支
message人可读(勿泄露栈)
request_id链路追踪

REST vs RPC / gRPC​

REST + JSONgRPC
协议HTTP/1.1 或 HTTP/2HTTP/2
契约OpenAPI 常见Protobuf
场景对外 API、浏览器内部微服务、高性能
流式SSE / WebSocket 另说原生 streaming

选型:对外 REST/OpenAPI;内部高频调用 gRPC 很常见。

与认证的关系​

401/403 边界、Token 放 Header 见 认证与授权。网关层统一鉴权与路由见 API 网关设计与实现。

常见误解​

  1. 「REST 不能有任何 RPC 味道」—— pragmatic REST 即可,别教条
  2. 「POST 一定不幂等」——可用幂等键设计幂等 POST
  3. 「版本写在 body 里就行」——网关与缓存难处理

面试速记​

  1. RESTful 核心? 资源、HTTP 方法语义、状态码、无状态。
  2. 401 vs 403? 未登录 vs 无权限。
  3. 如何保证 POST 幂等? Idempotency-Key、业务唯一键。
  4. 深分页问题? OFFSET 大页慢;改 cursor/keyset。
  5. REST 和 gRPC 怎么选? 对外 vs 内部、契约、性能、浏览器支持。