上个月帮一个团队做接口审查,发现他们的“RESTful 接口”几乎所有请求都是 POST,HTTP 状态码一律返回 200,错误信息全部塞在响应体里。更麻烦的是,同一套服务内部调用用的却是 Dubbo RPC,两套接口各自为政,文档对不上,排查线上问题全靠人肉翻日志。这个场景我相信不少做微服务的同学都遇到过。
微服务接口设计这件事,难的不是某个单一技术点,而是你需要在 RESTful 和 RPC 这两套风格之间做取舍,还要让它们在一个系统里长期共存、平滑演进。这篇文章我结合自己多年微服务项目的实际经验,把接口规范设计、兼容方案、生产环境排障和治理方法一次性讲透,适合在微服务架构里做后端开发、架构设计、以及正在从单体转微服务的团队参考。
1. 别急着选框架:先分清 RESTful 与 RPC 的适用边界
很多团队一上来就纠结“我们到底用 RESTful 还是 RPC”,然后开始争论哪个更先进。说实话,这个争论多半是伪命题。RESTful 和 RPC 是两种不同心智模型的接口风格,解决的不是同一类问题的两套方案,选型的第一步应该是想清楚你的调用方是谁、调用频率多高、跨团队边界在哪。
1.1 相同的业务,两种完全不同的表达方式
同样一个“查询订单”的操作,RESTful 的表达方式是面向资源的:
bash复制GET /api/v1/orders/{orderId}
RPC 的表达方式是面向方法的:
protobuf复制service OrderService {
rpc QueryOrder(QueryOrderRequest) returns (QueryOrderResponse);
}
RESTful 把业务对象抽象成资源,用 HTTP 动词表达对这个资源的操作意图。RPC 则是把业务过程抽象成方法调用,客户端像是调用本地函数一样调用远端方法。这两种思维方式决定了后续所有的接口命名、参数设计、错误处理方式。
我见过不少团队用“伪 RESTful”的方式写接口,路径是 /api/order/getOrderById 或者 /api/order/queryOrderList,这本质上是用 RESTful 的壳套 RPC 的思维。不是说这种写法完全不能用,而是它既享受不到 RESTful 的语义化好处,也没有 RPC 的契约严谨性,两边不讨好。
1.2 从协议栈看差异:RESTful 建立在 HTTP 语义上,RPC 建立在二进制管道上
RESTful 接口直接依赖 HTTP 协议——请求方法、状态码、Header、缓存机制都是 HTTP 原生能力。这意味着网关、负载均衡器、监控系统、浏览器这些基础设施天然就能理解你的接口语义。一个 GET 请求可以被 CDN 缓存,一个 404 状态码能被监控系统直接识别,这是 RESTful 的巨大优势。
RPC 框架则通常走自定义协议,传输效率和序列化效率优先。以 gRPC 为例,虽然它底层用的是 HTTP/2,但它的请求路径是方法名而不是资源 URI,状态码也是自定义的 gRPC 状态码,不是 HTTP 状态码。Dubbo 默认的 Dubbo 协议更是完全自定义的 TCP 二进制协议,HTTP 基础设施完全无法感知。
这里有个常见的误解:有人觉得“gRPC 也走 HTTP,所以它也是 RESTful”,这是不对的。判断标准不是底层是不是 HTTP,而是接口是否围绕资源建模、是否使用 HTTP 方法语义。gRPC 本质上是方法调用,即使跑在 HTTP/2 上也是 RPC。
1.3 一张表看清选型边界
| 维度 | RESTful | RPC(gRPC / Dubbo) |
|---|---|---|
| 心智模型 | 资源 + HTTP 动词 | 方法 + 消息契约 |
| 序列化 | JSON 为主 | Protobuf、Hessian 等二进制 |
| 跨语言支持 | 天然支持 | gRPC 好,Dubbo 偏 Java |
| 浏览器调用 | 直接支持 | gRPC 需 gRPC-Web 代理 |
| 调试便捷度 | curl 直接调 | 需要专用工具 |
| 性能 | 中(JSON 解析开销) | 高(二进制 + 连接复用) |
| 契约管理 | OpenAPI 文档 | IDL 文件强约束 |
| 典型场景 | 开放 API、BFF、跨组织对接 | 内部服务间高频调用 |
我的观点很明确:对外暴露的 API(尤其是面向第三方或前端的)优先 RESTful,内部服务间高频调用链路优先 RPC。这不是技术洁癖,而是工程现实——外部调用方不确定会用什么样的技术栈,RESTful 的通用性最好;内部链路性能敏感、调用关系复杂,RPC 的契约和性能优势能显著降低沟通成本。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. RESTful 规范落地:资源建模与状态码语义
选定了 RESTful 之后,真正考验经验的是细节规范的落地。一个团队的接口规范如果只写了“用 RESTful 风格”,那相当于什么都没写。我在这里给出一个可以直接抄的规范框架。
2.1 URI 设计:名词复数、层级嵌套和查询参数边界
资源路径统一用名词复数,不用动词。资源和资源之间的关系用层级嵌套表达,层级不要超过两层。例如:
bash复制# 正确
GET /api/v1/orders
GET /api/v1/orders/{orderId}
GET /api/v1/orders/{orderId}/items
POST /api/v1/orders
PUT /api/v1/orders/{o
