成为AI全栈 - 第3课:路由 RESTful Elysia 状态码 设计规范
从今天开始, 你是架构师,学会关键词就行,代码让AI实现😁
今天你会学到这些关键词
| 关键词 | 一句话解释 |
|---|---|
| 路由 | URL 到功能的映射,如 /users → 查询用户 |
| RESTful | API 设计规范,用 HTTP 方法表示操作 |
| Elysia | 高性能 Web 框架,链式 API 设计 |
| 状态码 | HTTP 响应状态,如 200 成功、404 找不到 |
一句话总结:用 Elysia 设计 RESTful 路由,让 API 清晰、一致、可预测。
上节课回顾
我们用 AI 生成了一个简单的后端服务:
sql
GET / → 返回 Hello World
GET /time → 返回当前时间
今天我们要深入理解:路由。
路由是什么?
一句话:路由就是 URL 到功能的映射。
bash
用户访问的 URL → 后端执行的功能
─────────────────────────────────────────
GET /users → 查询所有用户
GET /users/123 → 查询 ID 为 123 的用户
POST /users → 创建新用户
PUT /users/123 → 更新 ID 为 123 的用户
DELETE /users/123 → 删除 ID 为 123 的用户
RESTful API 设计规范
RESTful 是一种 API 设计规范,让接口更清晰、统一。
核心原则
1. 用 URL 表示资源
bash
/users → 用户资源
/orders → 订单资源
/products → 商品资源
注意, 所有资源都用复数命名
2. 用 HTTP 方法表示操作
| 方法 | 操作 | 示例 |
|---|---|---|
| GET | 查询 | GET /users 查询所有用户 |
| POST | 创建 | POST /users 创建用户 |
| PUT | 更新(全部) | PUT /users/123 更新用户123 |
| PATCH | 更新(部分) | PATCH /users/123 部分更新 |
| DELETE | 删除 | DELETE /users/123 删除用户123 |
| 注意, 大部分编辑功能我们都应该用PATCH方法而不是PUT |
3. 用状态码表示结果
| 状态码 | 含义 | 场景 |
|---|---|---|
| 200 | 成功 | 请求正常处理 |
| 201 | 创建成功 | 新建资源成功 |
| 400 | 请求错误 | 参数不对 |
| 401 | 未授权 | 需要登录 |
| 404 | 找不到 | 资源不存在 |
| 500 | 服务器错误 | 后端出错了 |
实战:设计用户管理 API
我们要设计一套用户管理的 API,包含增删改查。
API 设计表
| 功能 | 方法 | URL | 请求体 | 响应 |
|---|---|---|---|---|
| 查询所有用户 | GET | /users | - | 用户列表 |
| 查询单个用户 | GET | /users/:id | - | 单个用户 |
| 创建用户 | POST | /users | {name, email} | 新用户 |
| 更新用户 | PUT | /users/:id | {name, email} | 更新后的用户 |
| 删除用户 | DELETE | /users/:id | - | 删除结果 |
统一响应格式
json
{
"success": true,
"data": { ... },
"message": "操作成功"
}
用 Trae 生成代码
复制这段提示词:
markdown
用 Elysia 框架创建用户管理 RESTful API
要求:
1. 内存存储(用 Map 或数组模拟数据库)
2. 实现以下接口:
- GET /users - 查询所有用户
- GET /users/:id - 查询单个用户
- POST /users - 创建用户(body: {name, email})
- PUT /users/:id - 更新用户
- DELETE /users/:id - 删除用户
3. 统一响应格式:
{ success: boolean, data: any, message: string }
4. 状态码规范:
- 200: 成功
- 201: 创建成功
- 404: 用户不存在
- 400: 参数错误
5. 添加请求日志
请生成完整的 TypeScript 代码
Trae 会生成类似这样的代码:
typescript
import { Elysia } from "elysia";
// 内存存储
const users = new Map();
let idCounter = 1;
const app = new Elysia()
.onRequest(({ request }) => {
console.log(`${request.method} ${new URL(request.url).pathname}`);
})
// 查询所有用户
.get("/users", () => {
return {
success: true,
data: Array.from(users.values()),
message: "查询成功"
};
})
// 查询单个用户
.get("/users/:id", ({ params: { id }, set }) => {
const user = users.get(id);
if (!user) {
set.status = 404;
return { success: false, data: null, message: "用户不存在" };
}
return { success: true, data: user, message: "查询成功" };
})
// 创建用户
.post("/users", async ({ body, set }) => {
const { name, email } = body as { name: string; email: string };
if (!name || !email) {
set.status = 400;
return { success: false, data: null, message: "name 和 email 不能为空" };
}
const newUser = {
id: String(idCounter++),
name,
email,
createdAt: new Date().toISOString()
};
users.set(newUser.id, newUser);
set.status = 201;
return { success: true, data: newUser, message: "创建成功" };
})
// 更新用户
.put("/users/:id", async ({ params: { id }, body, set }) => {
const user = users.get(id);
if (!user) {
set.status = 404;
return { success: false, data: null, message: "用户不存在" };
}
const { name, email } = body as { name?: string; email?: string };
const updatedUser = {
...user,
...(name && { name }),
...(email && { email }),
updatedAt: new Date().toISOString()
};
users.set(id, updatedUser);
return { success: true, data: updatedUser, message: "更新成功" };
})
// 删除用户
.delete("/users/:id", ({ params: { id }, set }) => {
const user = users.get(id);
if (!user) {
set.status = 404;
return { success: false, data: null, message: "用户不存在" };
}
users.delete(id);
return { success: true, data: null, message: "删除成功" };
})
.listen(3000);
console.log(`Server running at http://localhost:${app.server?.port}`);
💡 Node.js 用户注意:需要修改代码使用 Node 适配器
typescriptimport { Elysia } from "elysia"; import { node } from "@elysiajs/node"; // ... 路由代码 ... .listen(3000, node); // ← 加上 node 适配器
测试 API
启动服务:
bash
bun run index.ts
1. 创建用户:
bash
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"name": "张三", "email": "zhangsan@example.com"}'
返回:
json
{
"success": true,
"data": {
"id": "1",
"name": "张三",
"email": "zhangsan@example.com",
"createdAt": "2024-01-15T10:30:00.000Z"
},
"message": "创建成功"
}
2. 查询所有用户:
bash
curl http://localhost:3000/users
3. 查询单个用户:
bash
curl http://localhost:3000/users/1
4. 删除用户:
bash
curl -X DELETE http://localhost:3000/users/1
好 API 的 3 个标准
1. 清晰
URL 一看就知道是做什么的:
bash
✅ GET /users/orders → 查询用户的订单
❌ GET /getUserOrderData → 不够简洁
2. 一致
同样的场景用同样的格式:
css
✅ 所有列表接口都返回 { success, data: [], message }
✅ 所有错误都返回 4xx/5xx 状态码
3. 可预测
符合 RESTful 规范,前端一看就懂:
bash
/users → 用户相关
/orders → 订单相关
核心收获
今天学习了:
✅ 路由 = URL 到功能的映射 ✅ RESTful 规范 = 用 HTTP 方法表示操作 ✅ 状态码 = 表示请求结果 ✅ 统一响应格式 = 让前端好处理
下节课预告
第4课:不用懂 SQL,AI 帮你操作数据库
我们将:
- 理解数据库和 ORM
- 用 Drizzle ORM 操作 SQLite
- 把内存存储换成真正的数据库
思考题:
如果要设计一个文章管理 API,你会怎么设计路由?
提示:文章有标题、内容、作者、发布时间。
欢迎在评论区分享你的设计。
如果觉得有帮助,欢迎点赞、在看、转发。