3. 接口设计原则:RESTful 与 GraphQL 的选型及分级接口规范
接口设计这件事,我一直觉得是「先想清楚再动手」的典型场景。你拿到一个数据分级的需求,第一反应是什么?很多人直接上 RESTful,也有人看别人用 GraphQL 就跟着用。说实话,我早期也踩过这个坑。
有一天,我在做内部数据中台对接外部业务系统时,发现同一个 API 返回了 50 多个字段,前端只用了 3 个。负载倒是没多大,但每次排查问题都要拖回一堆无用数据,数据库连接池都涨红了。后来我才意识到——选型不是比谁时髦,而是看你的数据分级和调用场景。
RESTful 与 GraphQL:两个流派,各有利弊
先说 RESTful。它是我用了七八年的老伙计,规规矩矩的 CRUD,资源化设计,一个 URL 对应一种资源。我习惯把 GET 请求的查询参数老老实实列出来,后端做分页、排序、过滤,大家都看得懂。但你想想,如果一次需要查「用户信息+最近 10 条订单+当前积分」,RESTful 就得调三个接口,或者专门开一个聚合接口。前者网络开销大,后者维护成本高。
GraphQL 恰好解决了这个痛点。客户端可以声明自己要什么字段,一次请求拿回嵌套数据。我在一个数据报表项目中试过,前端同事激动得不行——他们再也不用等后端加字段了。但问题也明显:查询复杂度不可控,一个深度嵌套的 query 可能拖垮数据库,尤其是当接口暴露给外部不可信客户端时。
下面这张图是我在团队内部分享时画的选型决策流程,你一看就明白。
你看,决策路径并不复杂。但真正让我把它落地的,是后面要讲的分级规范。
分级接口规范:落地才是硬道理
我自己在负责数据平台时,把接口分为三个等级:L1(公开)、L2(内部)、L3(受限)。每个等级对应不同的接口设计约束。下表是我当时定下来的规范,后来被多个团队参考了。
| 分级 | 适用数据 | 推荐接口风格 | 额外约束 |
|---|---|---|---|
| L1 | 公开数据(例如产品列表、公告) | RESTful 或 GraphQL | 可缺省认证,但需限流 |
| L2 | 内部业务数据(用户概况、订单状态) | RESTful 首选,GraphQL 可选 | 强制 + 操作日志 |
| L3 | 受限数据(身份证、金融流水、密钥) | 仅限 RESTful | 字段级权限 + 签名校验 + 全审计 |
实战案例:一次接口改造的血泪史
有一次,我们给银行做数据开放平台,对方要求所有外部接口走 GraphQL。我一开始觉得没问题,直到上线前安全审计发现——一个深度为 5 层的嵌套查询,可以直接通过关联关系把客户A的所有交易记录拽出来,尽管它只被授权查客户B的数据。这就是 GraphQL 的「深度+权限」叠加风险。
我后来怎么解决的?我把 L3 数据全部剥离出来,强制走 RESTful 接口,并且在网关层做了「查询白名单」——每个 query 只能命中预先注册的字段集合。L1 和部分 L2 数据继续用 GraphQL,前端体验提升不少。说白了,就是「分级 + 混合」。
如何落地分级接口规范?
- 先定义数据分级清单——哪些属于 L1/L2/L3,和安全团队一起定。
- 再选接口风格——L3 强制 RESTful,L1/L2 看业务是否需要灵活查询。
- 最后加网关层——不管用什么风格,统一经过 APIGateway,实现限流、审计、字段过滤。
嗯,这套方法我在多个项目里验证过。写过 RESTful 也写过 GraphQL,最后发现没有银弹。关键是把数据分级这个基础打牢,接口风格只是上层建筑。