后端 API 优化实战:字段补充与结果排序
在实际开发中,接口返回数据不一致、缺少关键字段、返回结果无序等问题经常困扰前端同学。本文记录了两个典型的后端 API 优化场景:为接口补充友好字段、为统计数据添加排序,分享问题定位思路和最小侵入式修改方案。
前言
在一次需求开发中,前端反馈了两个问题:一是水情汇总接口返回的测站类型是代码(如 ZQ),需要额外查询转换;二是管理单位统计接口返回的数据顺序是随机的,展示效果不佳。这两个问题都属于”不影响功能但影响体验”的类型,本文记录解决过程。
场景一:为接口新增友好字段
问题背景
/api/water/summary/list 接口返回的 STTP(测站类型代码)是英文缩写,比如 ZQ 代表水文站、ZZ 代表水位站。前端展示时需要额外维护一套映射关系,将代码转换为中文名称。
而同一个项目中,/basic/b/list 接口已经返回了 stationTypeName 字段,直接提供中文名称。两处实现不一致,增加了前端的维护成本。
解决方案
参照 /basic/b/list 的实现,为 summary/list 接口新增 stationTypeLabel 字段,复用现有的 MappingService.getStationTypeMap() 获取测站类型映射。
实现步骤
1. DTO 新增字段
在响应 DTO 中添加新字段:
1 | // WaterSummaryListResponseDTO.java |
2. Controller 注入 MappingService
复用现有的映射服务,避免重复造轮子:
1 | // WaterSummaryController.java |
3. 数据转换时填充字段
在 DTO 转换逻辑中填充新字段,注意批量获取映射避免 N+1 问题:
1 | // 批量转换时获取测站类型映射 |
返回示例
优化后的接口返回:
1 | { |
场景二:统计接口结果排序
问题背景
/basic/b/statistics?staticType=unit 接口返回各机构的测站统计数据,但 data 数组中的顺序是随机的。前端展示时希望按测站总数(total)从大到小排序,让数据量大的机构排在前面。
解决方案
在业务层返回数据前添加排序逻辑,保持对原有代码的最小侵入。
实现步骤
在 StStbprpUnitStatisticsBiz 的两个统计方法中,于 return dataList 前添加一行排序代码:
1 | // StStbprpUnitStatisticsBiz.java |
需要修改的方法:
statisticsForSecondLevel()statisticsForThirdLevel()
影响分析与注意事项
字段新增场景
| 检查项 | 状态 | 说明 |
|---|---|---|
| DTO 使用范围 | ✅ 安全 | DTO 仅在 Controller 内部使用 |
| 方法签名变更 | ✅ 安全 | 转换方法是 private,无外部调用 |
| 测试文件 | ✅ 无需修改 | 现有测试是集成测试 |
| API 兼容性 | ✅ 向后兼容 | 新增字段不影响现有前端 |
注意事项:如果使用了缓存(如 cache=1),旧缓存数据不包含新字段,反序列化后为 null。可以等待缓存过期(30 天),或手动清除 Redis 缓存:KEYS water:summary:*
结果排序场景
| 检查项 | 状态 | 说明 |
|---|---|---|
| 业务逻辑 | ✅ 无侵入 | 只在返回前添加排序 |
| 分页功能 | ✅ 无影响 | 该接口无分页 |
| API 兼容性 | ✅ 向后兼容 | 数据结构不变,只改变顺序 |
经验总结
本次优化涉及两个小改动,但体现了几个重要的开发原则:
- 复用现有服务:
MappingService已经提供了类型映射,直接复用避免重复维护 - 保持一致性:不同接口的返回结构应保持一致,减少前端适配成本
- 最小侵入修改:排序逻辑只在返回前添加,不侵入核心业务流程
- 批量获取映射:避免在循环中单独查询,防止 N+1 问题
- 向后兼容:新增字段不破坏现有功能,排序不改数据结构
这些”小优化”看似不起眼,但积累起来能显著提升 API 的易用性和前端开发体验。
结语
后端开发不仅是实现功能,还要关注 API 的友好性和一致性。希望这两个小案例能给你带来一些启发,在实际项目中遇到类似问题时,可以快速定位并优雅解决。