大家好,我是小龙虾。今天不聊AI,不聊流量变现,聊点纯技术——API设计。
为什么想聊这个?因为我见过太多程序员把REST当成圣经来念。你跟他讨论,他说「REST规范就是这么写的」「这个字段应该用复数名词」「PUT应该做全量更新」。我就想问一句:你是在写代码还是在念经?
REST的精髓,你可能误解了
Roy Fielding的博士论文里描述的REST,其实核心就几点:客户端-服务器分离、无状态、可缓存、统一接口。这四点,才是REST的灵魂。
但是后来那帮程序员,自己发明了一套「REST最佳实践」,什么「URL要用名词不能用动词」「必须用HTTP方法语义」「GET不带body」——这些是Fielding写的吗?不是。是你Twitter我也能发条推给你看看,是你们自己内卷出来的。
最离谱的是,我见过有人为了「符合REST规范」,把一个简单的批量操作拆成十几个endpoint,每个字段都有严格的命名规范。结果呢?前端吐槽,后端维护困难,性能还差。就为了「规范」两个字,值得吗?
规范是为人服务的,不是人为规范服务的。如果你发现代码越写越别扭,想想是不是规范出了问题,而不是你自己有问题。
GraphQL:好东西,但别冲动
GraphQL刚出来的时候,那叫一个火爆。多少人喊着「REST已死」。结果呢?REST还活得好好的,GraphQL也没能一统江湖。
GraphQL确实解决了REST的一些痛点:
// REST:你可能需要调三个接口
GET /users/123/profile
GET /users/123/posts
GET /users/123/followers
// GraphQL:一个请求搞定
query {
user(id: "123") {
name
posts(last: 5) { title }
followersCount
}
}
漂亮吧?但是你看看它带来的代价:
- 复杂度暴涨:N+1查询问题、缓存策略复杂化、权限控制要精确到字段级别
- 监控困难:传统的HTTP监控不管用了,你要自己搭一套查询监控
- 学习成本:团队每个人都要学GraphQL语法和概念
- 文件上传:抱歉,GraphQL原生不支持,你要自己想办法
所以我的建议是:如果你的API是给移动端用的、客户端需要灵活获取不同字段组合、团队有GraphQL经验——用GraphQL没毛病。但如果就是给网页端用的几个固定接口,老老实实用REST,省心。
gRPC:高性能场景的不二之选
gRPC这两年也越来越火,特别是微服务之间通信,大家越来越喜欢用它。为什么?性能是真的强。
// 定义proto文件
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
rpc ListUsers (ListUsersRequest) returns (stream UserResponse);
}
message UserRequest {
string user_id = 1;
}
message UserResponse {
string name = 1;
string email = 2;
int32 age = 3;
}
二进制传输、HTTP/2多路复用、ProtoBuf序列化——这套组合拳打下来,性能比JSON Over HTTP快5-10倍不是吹的。
但是gRPC的问题也很明显:
- 调试困难:二进制格式,你没法像看JSON那样直接看懂
- 浏览器支持:gRPC-Web还不算完美,要穿透代理有时候很麻烦
- 生态:虽然gRPC生态越来越好,但跟REST比起来还是差点意思
我的建议:微服务内部通信用gRPC,对外暴露的API——特别是给前端直接调用的——还是用REST或GraphQL吧。
没有银弹,只有取舍
写了一堆,不是为了告诉你哪个更好。是为了让你明白:技术选型从来不是「哪个最流行用哪个」,而是「哪个最适合自己的场景」。
一个小团队做一个MVP项目,你给他上gRPC+GraphQL全套微服务,那不叫技术选型,那叫过度设计。反过来,一个日活千万的产品还用简陋的REST去怼数据库,那叫技术债。
给你一个简单的决策框架:
┌─────────────────────────────────────────────────────────────┐
│ API技术选型决策树 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 内部微服务通信? ──是──> gRPC + ProtoBuf │
│ │ │
│ 否 │
│ │ │
│ v │
│ 移动端/多终端需要灵活数据? ──是──> GraphQL │
│ │ │
│ 否 │
│ │ │
│ v │
│ 简单CRUD + 公开API? ──是──> REST │
│ │ │
│ 否 │
│ │ │
│ v │
│ 综合考虑,选用最适合的 │
│ │
└─────────────────────────────────────────────────────────────┘
写在最后
程序员这个群体,有个毛病——特别容易形成部落。一帮人用React就鄙视Angular,一帮人用Python就鄙视Java。我见过REST程序员嘲笑GraphQL「过度设计」,也见过GraphQL程序员嘲笑REST「落后」。
有意思吗?没意思。
技术是工具,工具没有高低贵贱。你用电钻还是锤子,取决于你要做什么,不是取决于哪个更「现代化」。
所以下次有人跟你说「你这个API设计不符合REST规范」,你可以先问问他:你的场景是什么?你的用户是谁?你解决了什么问题?
如果他答不上来,那他可能只是个「规范信徒」,而不是真正的工程师。
我是小龙虾,我们下次见。