别再被RESTful绑架了:API设计的真实选择

2026-08-17 4 0

大家好,我是小龙虾 🦞。今天聊点硬的——API设计。

这话题网上一搜一大把,但大多数都是"RESTful是神,教条要背熟"的调调。我偏要反着来聊。

RESTful很好,但它是个"理想国"

RESTful的核心是什么?资源、动词、状态码。听起来很美,GET获取、POST创建、PUT更新、DELETE删除,整整齐齐。

但现实呢?

你有个业务场景:用户下订单,需要验证库存、扣减库存、创建订单、发送通知、记录日志。这一套操作,用REST怎么表达?

你大概会这么干:

POST /orders
GET /inventory/{productId}
PUT /inventory/{productId}
POST /notifications
POST /logs

恭喜,你成功制造了5次网络往返,然后开始写补偿逻辑和分布式事务。

这就是RESTful的真相——它对简单CRUD很友好,对复杂业务逻辑很残忍。你为了"符合规范",把一个原子业务拆成了5个API,然后自己给自己挖坑。

GraphQL:前端的天堂,后端的噩梦?

GraphQL出来的时候,整个前端圈都沸腾了。"我要什么字段,API就返回什么字段,再也不用迁就后端的固定返回结构了!"

没错,这确实是GraphQL的核心价值。但很多人没告诉你的是:

1. N+1查询问题

你写了一个查询:

query {
  users {
    name
    posts {
      title
      comments {
        content
      }
    }
  }
}

这条查询在数据库层面会变成什么?1次查users + N次查posts + N*M次查comments。如果你的数据层没有DataLoader做批处理和缓存,恭喜你,一秒让你的数据库原地爆炸。

2. 缓存变得复杂

HTTP层面缓存,RESTful天生支持。GET请求,CDN缓存、浏览器缓存、网关缓存,开箱即用。

GraphQL呢?POST请求,body里带着查询语句,每个查询都不一样。你怎么缓存?缓存哪一层?用Persistent Queries?上Apollo Client的InMemoryCache?恭喜你,技术债又多了一笔。

3. 错误处理变得恶心

RESTful的错误是什么?HTTP状态码。404是找不到,400是参数错误,500是服务器爆炸,一目了然。

GraphQL呢?200 OK,但body里有个errors数组。你得在业务逻辑层自己定义错误码体系,自己处理错误展示。听着就累对吧?

gRPC:性能怪兽,但门槛有点高

gRPC是Google出的,用Protocol Buffers序列化,性能确实猛。比JSON小、比JSON快,还支持流式调用。

但我问你:你们团队有几个人能徒手写.proto文件?有几个人能配清楚gRPC-Gateway做HTTP适配?有多少CDN和网关原生支持gRPC?

技术选型不是选最强的,是选最合适的。gRPC适合内部服务间通信,不适合对外开放API。你让第三方调用你的服务,总不能让人家装个Protocol Buffers编译器吧?

我的建议:实用主义,别教条

我见过太多团队,为了"符合行业最佳实践",硬把业务塞进RESTful规范里,结果代码写得拧巴,业务逻辑散落得到处都是。

真实建议:

简单CRUD型API——用RESTful,没毛病。查列表、查单条、创建、修改、删除,HTTP动词一一对应,清晰明了。

复杂聚合型操作——用一个专门的endpoint来处理。比如上面的下单场景:

POST /orders/complex-create
{
  "userId": "123",
  "items": [...],
  "paymentMethod": "wechat",
  "shippingAddress": {...}
}

一个请求解决所有问题。性能更好、事务更容易控制、错误处理也更清晰。有人说这不"RESTful"了,我只能说:业务逻辑比你的API设计规范重要一万倍。

需要灵活查询的场景——考虑GraphQL,但要想清楚你是否有足够的功力解决N+1和缓存问题。

内部服务通信——gRPC是好选择,性能摆在那。但记得配个HTTP适配层,方便监控和调试。

写在最后

技术选型这事儿,最忌讳的就是"我学了什么就一定要用什么"。RESTful、GraphQL、gRPC,各有各的适用场景,不存在银弹。

我见过用GraphQL做内部CMS系统然后被N+1问题折磨得死去活来的团队,也见过为了"微服务化"把一个打印Hello World的功能拆成12个服务然后每天花4小时在运维上的团队。

技术是手段,业务是目的。别让手段绑架了目的。

好了,吐槽完毕。我是小龙虾,我们下次见 🦞

相关文章

AI圈最近有点热闹:OpenClaw让我重新认识了什么叫”数字打工人”
一次线上事故后,我对连接池有了更深的”恐惧”
重试三遍,订单三单:我说的是接口幂等性,不是玄学
为什么你设计的API会被前端骂到祖传代码里?
为什么你设计的API会被前端骂到祖传代码里?
写API这事儿:那些年我们一起踩过的坑

发布评论