Restful api 和 RPC api的区别
RESTful vs RPC 风格 API
核心区别
| RESTful | RPC | |
|---|---|---|
| 设计哲学 | 围绕资源(名词) | 围绕动作(动词) |
| URL 风格 | /users/123 |
/getUser、/createOrder |
| HTTP 方法 | GET/POST/PUT/PATCH/DELETE 各有语义 | 基本只用 POST |
| 典型代表 | GitHub REST API | gRPC、tRPC、GraphQL |
对比示例:
── RESTful ──
GET /api/users/123 获取用户
POST /api/users 创建用户
PUT /api/users/123 更新用户
DELETE /api/users/123 删除用户
PATCH /api/users/123/email 修改邮箱
── RPC ──
POST /api/getUser { id: 123 }
POST /api/createUser { email, password }
POST /api/updateUser { id: 123, name: "new" }
POST /api/deleteUser { id: 123 }
POST /api/changeEmail { id: 123, email: "new" }
为什么越来越多项目倾向 RPC
1. REST 的"资源映射"经常很牵强
# 这些操作该用什么 HTTP 方法?什么资源?
- 登录 → POST /sessions? POST /auth/login?
- 发送验证码 → POST /verification-codes? POST /sendCode?
- 批量删除 → DELETE /users?ids=1,2,3?(body 放哪?)
- 转账 → PUT /accounts/123?(从哪转到哪?)
业务操作本质是动作,硬塞进"资源 + HTTP 方法"的模型里很别扭。
2. POST 最灵活
- GET 不能有 body(复杂查询怎么办?URL 有长度限制)
- PUT vs PATCH 语义争论不断
- DELETE 带不带 body 各浏览器实现不一
- POST 什么都能做,没有这些限制
3. 类型安全的需求
现代前端(TypeScript)需要端到端类型安全。RPC 框架天然支持:
// tRPC — 前后端共享类型,调用像本地函数
const user = await trpc.user.getById.query({ id: 123 });
// ^自动推断类型 User
// GraphQL — 按需查询
const { data } = await client.query({
query: gql`
{
user(id: 123) {
name
email
}
}
`,
});
REST 没有内置的类型共享机制,需要额外的 OpenAPI/Swagger 工具链。
4. 实际开发效率
// REST 风格要纠结的问题:
// - 这个操作是 PUT 还是 PATCH?
// - URL 层级怎么设计?/users/123/orders 还是 /orders?userId=123
// - 批量操作的 URL?
// - 嵌套资源怎么表达?
// RPC 风格直接命名:
POST / api / user.create;
POST / api / user.updateEmail;
POST / api / order.batchCancel;
// 不纠结,直接写
5. 微服务/内部通信
公司内部服务间通信基本是 gRPC(二进制协议、高性能、强类型),不用 REST。对外公开 API 才考虑 REST,因为它更"通用"。
REST 仍然有价值的场景
- 开放 API / 第三方集成:REST 规范通用,任何语言/工具都能调用,Postman、curl 直接测
- 缓存友好:GET 请求天然可被浏览器/CDN 缓存,RPC 全是 POST 无法利用 HTTP 缓存
- CRUD 为主的简单业务:博客文章、商品列表这类纯 CRUD,REST 映射很自然
- 可发现性:URL 本身就是文档,
GET /api/users一看就懂
我们项目的选择
我们的 auth API 实际上是 RPC 风格:
POST /api/auth/register
POST /api/auth/login
POST /api/auth/logout
POST /api/auth/verify-email
POST /api/auth/request-password-reset
POST /api/auth/reset-password
POST /api/auth/resend-verification
GET /api/auth/me
这些都是动作,不是资源 CRUD,用 RPC 风格是正确的选择。唯一的 GET 是 /me(读取当前用户,纯查询可缓存)。
总结
REST 是 2000 年代的正统,RPC 是 2020 年代的务实。
REST 适合对外开放、资源导向的场景;RPC 适合内部系统、动作导向、追求类型安全的场景。大多数现代全栈项目用 RPC 更高效。
