Yasin

Yasin

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 更高效。