列表筛选 DTO 契约要先于 ORM 细节
· 阅读需 2 分钟
很多项目里,列表筛选之所以越做越乱,不是 Sequelize 本身的问题,而是接口层直接暴露了 ORM 的思路。前端传什么字段、后端就原样拼进查询对象,结果筛选协议和数据库实现被彻底绑在一起。
我更习惯先定义一层筛选 DTO,例如关键字、状态、时间区间、标签、排序字段,这一层只描述业务意图,不描述 Sequelize 的具体写法。服务层再把 DTO 翻译成 where、order、include。这样一来,前端不需要知道数据库里到底是 Op.like 还是全文索引,后端也能在不改接口的前提下优化查询。
这种拆法最大的收益是:
- 接口文档稳定,前端联调不会反复重写。
- 查询优化有空间,不会被请求参数格式锁死。
- 业务筛选项和 ORM 语法解耦,代码更容易维护。
DTO 契约先站稳,ORM 只是实现细节。这个顺序看着保守,实际上能省掉很多无谓返工。
为什么这类问题总会在线上阶段突然变贵
围绕「列表筛选 DTO 契约要先于 ORM 细节」这类判断,最容易被低估的地方,是大家前期总把它当成 ORM 写法偏好,而不是数据契约和查询边界。数据量小、调用方少的时候,字段命名、关联深度、分页方式、迁移顺序都像只是风格问题;一旦接口被更多页面复用,筛选、排序、统计和审计需求一起叠上来,之前没收住的边界就会同时在性能、排障和协作成本上爆出来。
落地时我会先卡住的检查项
- 先把输入 DTO、模型字段和最终 SQL 这三层对应关系看清,避免“接口语义已经变了,ORM 代码却还在偷偷兜底”。
- 把统计、明细、写操作和回滚路径拆开看,别让一个方便的查询顺手背上太多职责。
- 一旦这篇文章讨论的点已经影响到索引、事务或迁移顺序,就说明它不是微调,而是该补正式约束了。
