RESTful API 基础:HTTP 方法、URI 设计、状态码
RESTful API 说起来很简单,就是把网络上的资源通过 URI 暴露出来,然后用 HTTP 方法操作它们。但我在十几年前刚接触这个概念时,踩了不少坑。
说白了,REST 不是一套协议,而是一组设计约束。你照着做,接口就清晰;你不照着做,后期维护就得抓狂。今天我把最核心的三块展开聊:
- HTTP 方法 – 你到底想对资源做什么?
- URI 设计 – 资源长什么样?怎么给它起名?
- 状态码 – 服务器到底处理得怎么样了?
HTTP 方法:不只是 CRUD
大多数人把 HTTP 方法等同于数据库的增删改查(CRUD),这个理解方向是对的,但不够精确。RESTful API 里,每个方法都有明确的语义,用错了会让调用方困惑。
来看一张常见方法的对比表:
| 方法 | 语义 | 幂等? | 安全? | 典型场景 |
|---|---|---|---|---|
GET |
获取资源 | ✓ | ✓ | 查询列表、查看详情 |
POST |
创建资源(或触发处理) | ✘ | ✘ | 注册用户、提交订单 |
PUT |
完全替换资源 | ✓ | ✘ | 更新用户全部字段 |
PATCH |
局部更新资源 | ✘(大多数实现) | ✘ | 只改用户昵称 |
DELETE |
删除资源 | ✓ | ✘ | 删除文章 |
具体到 Secrets 管理接口,我习惯把密钥资源设计成这样:
GET /secrets # 获取密钥列表(元信息)
POST /secrets # 创建新密钥
GET /secrets/{id} # 获取单个密钥详情
PUT /secrets/{id} # 全量更新密钥内容
PATCH /secrets/{id} # 更新密钥的元数据(比如过期时间)
DELETE /secrets/{id} # 删除密钥
你想想看,如果某个 API 用 GET 去修改资源,那语义就彻底乱套了。调用方不敢缓存,也不敢重试,整个系统的可预测性就打折扣。
URI 设计:命名即语义
URI 是资源的身份证。好的 URI 设计,看路径就能猜出资源和关系。我不喜欢那种 /api/getUserInfo?id=123 的风格,那更像是 RPC 而不是 REST。
几个我自己一直在用的原则:
- 用名词,不用动词。资源是名词(secrets, users, policies),动词留给 HTTP 方法。
- 用复数形式。
/secrets而不是/secret,这样集合和单个实例都能统一表达。 - 用层级表达关联。比如
/secrets/{id}/versions表示某个密钥的所有版本。 - 用查询参数做过滤、排序、分页。不要把它们塞进路径里。
- 避免太深的嵌套(超过三级)。我之前在项目里见过
/org/{orgId}/project/{projId}/env/{envId}/secret/{secretId},维护起来非常痛苦。
/getSecretsByUserId、/updateSecretValue 这种 RPC 风格。后来要加新功能,不得不新增几十个端点,整个接口文档又长又臭。后来全部重构了一遍,变成资源型 URI,工作量反而少了很多。别等到接口数量超过 50 个才想改,趁早。状态码:沟通的语言
状态码不是随便给个 200 或 500 就完事了。正确的状态码能让调用方不用读响应体就明白发生了什么。这也是 RESTful 设计里“自描述消息”的一部分。
我一般把常用状态码分成五组:
| 范围 | 含义 | 常用码 | 我的经验 |
|---|---|---|---|
| 2xx | 成功 | 200 OK, 201 Created, 204 No Content | POST 创建成功后尽量用 201,别偷懒只给 200 |
| 3xx | 重定向 | 301 Moved Permanently, 304 Not Modified | REST API 里 3xx 用得少,但 304 配合缓存很实用 |
| 4xx | 客户端错误 | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 429 Too Many Requests | 别把业务错误统统扔 400,分清 401/403/404 很重要 |
| 5xx | 服务端错误 | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable | 500 应该留给意外,不要让预期内的校验错误也返回 500 |
举个例子:用户请求一个不存在的密钥,你返回 200 + 响应体里写 "status": "not found"。嗯,这样调用方就得解析 body 才知道结果。正确的做法是返回 404。一步到位。
下面这张图把这三者的关系串起来——你在设计任何 REST 接口时,脑子里都应该过一遍这个流程:
你看,整个流程就是:客户端构造一个 URI + HTTP 方法请求,服务器处理完后返回带状态码的响应。每一步的规范程度,直接决定了接口的可用性和可维护性。
好了,这一轮的内容就到这。记住:方法选对、URI 起好、状态码给准,你的 RESTful API 就及格了。剩下的就是实践中不断打磨。