e5a5b9df5b
docs(ai-protocols): update AI protocols page with visual demos and detailed explanations style(git-demos): improve responsive design and layout for git visualization components refactor(ai-history): simplify and clean up demo components chore: update config to register new AI protocol components
4.8 KiB
4.8 KiB
API 设计:前后端的通用语言
💡 学习指南:这一章我们聊聊前后端如何高效对话。如果你被后端接口的命名搞晕过,或者不知道该返回 200 还是 404,这篇文章就是为你准备的。我们将通过一个交互式 Demo,带你理解 RESTful API 的设计精髓。
0. 先问一个问题:你有没有经历过这些噩梦?
场景一:接口猜谜
后端给你一个接口 /getUser,你调用了,返回 null。
你是传错了参数?还是数据库没数据?还是服务器崩了?完全不知道。
场景二:状态码撒谎
你收到了一个 HTTP 200 OK 的响应,心想“稳了”。 结果打开 Body 一看:
{
"code": 500,
"msg": "系统内部错误",
"data": null
}
浏览器缓存了它,监控系统认为它成功了,只有你的前端代码在风中凌乱。
场景三:版本地狱
项目迭代了三年,你的代码里充满了这样的 URL:
/api/v1/user/update/api/v2/user/update_new/api/user/update_final_real
API 设计就是为了解决这些问题。
它就像餐厅的菜单和点餐流程:规定了我们怎么点菜(请求)、怎么上菜(响应)、没菜了怎么办(错误处理)。
目前最流行的设计风格是 RESTful。
1. 核心概念:RESTful 是什么?
REST (Representational State Transfer) 听起来很学术,其实核心就三句话:
- 资源 (Resource):网络上的所有东西都是资源(用户、订单、商品)。
- 统一接口 (Uniform Interface):用标准的 HTTP 方法(GET, POST, DELETE)来操作这些资源。
- 无状态 (Stateless):每次请求都包含所有必要信息,服务器不记“你是谁”(除非你带了 Token)。
比喻:餐厅点餐
- URL 是桌号:
/tables/5(资源地址) - HTTP 方法是动作:
GET:看菜单POST:下单PUT:换一桌菜DELETE:吃完走人
2. 交互演示:RESTful API 全流程
别光听概念,我们来动手玩一下。 下面是一个模拟的“用户管理系统”。试着点击不同的场景,观察 客户端发出了什么 以及 服务端返回了什么。
💡 观察重点
- URL 是名词:注意看 URL 都是
/users或者/users/1,没有动词(如/getUsers)。因为 HTTP 方法(GET/POST)已经表示了动作。 - 状态码会说话:
- 创建成功返回
201 Created,而不是 200。 - 删除成功返回
204 No Content(没有 Body)。 - 找不到返回
404 Not Found。
- 创建成功返回
- 复数形式:通常使用
/users而不是/user,表示这是“用户集合”下的资源。
3. 设计黄金法则
3.1 URL 设计:让路径清晰
| 法则 | 正确 ✅ | 错误 ❌ | 原因 |
|---|---|---|---|
| 用名词,不用动词 | GET /products |
GET /getProducts |
HTTP 方法已经是动词了 |
| 用复数 | /users/1 |
/user/1 |
保持一致性,/users 代表集合 |
| 层级不要太深 | /users/1/orders |
/users/1/orders/2/items/3 |
超过 3 层建议拆分或用查询参数 |
| 使用连字符 | /user-profiles |
/userProfiles |
URL 对大小写敏感,连字符更易读 |
3.2 HTTP 方法:动作要有语义
- GET (查):安全且幂等。不管调用多少次,服务器状态不变。
- POST (增):不安全,不幂等。调用 10 次可能创建 10 个用户。
- PUT (改-全量):幂等。把 ID=1 的用户替换为新数据,替换 10 次结果一样。
- PATCH (改-局部):通常用于只修改一个字段(如只改密码)。
- DELETE (删):幂等。删除 ID=1 的用户,删 1 次和删 10 次,结果都是“用户没了”。
3.3 状态码:别只用 200
| 类别 | 状态码 | 含义 | 场景 |
|---|---|---|---|
| 2xx 成功 | 200 OK | 通用成功 | GET, PUT |
| 201 Created | 创建成功 | POST | |
| 204 No Content | 成功但无返回 | DELETE | |
| 4xx 客户端错 | 400 Bad Request | 参数错 | 必填项没填,格式不对 |
| 401 Unauthorized | 未登录 | 没有 Token 或 Token 过期 | |
| 403 Forbidden | 无权限 | 普通用户想删管理员 | |
| 404 Not Found | 找不到 | URL 错了或 ID 不存在 | |
| 5xx 服务端错 | 500 Internal Error | 崩了 | 代码抛异常了,数据库挂了 |
4. 总结
好的 API 设计是**“自解释”**的。
当你的前端同事看到 DELETE /api/orders/123,他不需要问你,就应该知道:
- 这是一个删除操作。
- 操作对象是 ID 为 123 的订单。
- 如果成功,应该收到 204 或 200。
- 如果失败,应该去看状态码是 4xx 还是 5xx。
这就是约定优于配置的力量。