系统设计 / 访问控制 · 从 RBAC 查表到 policy 判定函数 / 历史包袱:两套接口区分数据范围 待审核 10 / 23
历史包袱 · 两套接口

历史包袱:两套接口区分数据范围

很多老系统里存在两套几乎一样的接口:普通接口 /api/article/list 只返回「自己的」,管理接口 /api/admin/article/list 返回「全部」。它可以运行,但本质上是把 data-scope(见 Scope)硬编码进了 URL——用「走哪个接口」来区分「看到哪些数据」。

1 · 三个接口对同一用户的返回

一个 scope 为 Group 的 editor 处在两套接口之间的尴尬位置:普通接口给少了(只有自己的),管理接口给多了(连隔壁组也可见)。范围只能二选一,没有「本组」这一档。

图 1-1 · 同一个用户经三个接口取到的数据行。可点选接口,对照写死 Self、写死 Full 与 ScopeResolver 算出 Group 三种结果。

2 · 两种做法的差别

图 2-1 · 两套接口与统一接口 + ScopeResolver 的逐条对照。

注 · 这种写法当年出现的原因是实现成本低:早期只有「前台 / 后台」两个站点,各自一套接口最直接,当时也没有抽象出 scope 概念。负担是后来累积的——需求从「自己 / 全部」分化成「本组」「本店」「本区域」……每多一种范围就多一套接口,组合数量失控。

建议 · 迁移路径是先让 /admin/ 接口内部改走同一个 ScopeResolver(把前缀降级成「请求 scope=Full」的语法糖),两套接口共享一份逻辑;再逐步把前端切到统一接口;最后下线 /admin/ 前缀。关键是先统一底层、再收口入口,而不是一次性大重写。

警示 · 也不必一概否定接口分离。当「后台由另一个团队维护、另一套 BFF、风险模型完全不同」时,接口分离本身可能是合理的边界——只是不该用它来表达 data-scope。边界归边界,scope 归 scope,是两件独立的事。