Whistle 如何做接口数据模拟,resBody 和 resScript 怎么选?
Whistle 做数据模拟,最常见的目标不是“造一份假数据”这么简单,而是让前端在后端未完成、接口异常、网络慢、登录态变化时都能继续开发。选方法时可以先问一句:这个响应是固定的,还是要根据参数、请求头、登录状态动态变化?固定数据用 resBody 和 Values 更省事,动态逻辑再上 resScript 或插件。
固定响应用 resBody
如果只是让某个接口返回一段稳定 JSON,resBody 是成本最低的方式。它适合登录信息、配置开关、列表空态、错误码等场景。为了可维护,不建议把很长的 JSON 直接写在规则行里,最好放到 Values 文件中。
text# 简短响应可以直接写 api.example.com/api/ping resBody://{"code":0,"data":"pong"} # 复杂响应引用 Values api.example.com/api/user resBody://{mock-user.json}
json{ "code": 0, "data": { "id": 1001, "name": "测试用户", "roles": ["admin"], "vip": true } }
动态响应用 resScript
当响应需要读取 query、body、cookie,或者要模拟分页、随机失败、延迟时,resScript 更合适。脚本里应该显式设置 Content-Type,并处理缺省参数,否则前端拿到的响应可能和真实接口差异太大。
javascriptmodule.exports = function(req, res) { const page = Number(req.query.page || 1); const size = Number(req.query.size || 10); res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ code: 0, data: { list: Array.from({ length: size }, (_, i) => ({ id: (page - 1) * size + i + 1, title: `mock item ${i + 1}` })), page, total: 86 } })); };
textapi.example.com/api/list resScript://{mock-list.js}
异常和慢接口也要模拟
只模拟成功态是不够的,真实联调里更容易出问题的是超时、空列表、权限失败、字段缺失。可以准备几套 mock:success、empty、error、timeout,让前端页面在这些状态下都跑一遍。这样做比等后端临时改数据稳定,也更容易在评审前发现边界问题。
javascriptmodule.exports = function(req, res) { const type = req.query.type || 'success'; res.setHeader('Content-Type', 'application/json'); if (type === 'timeout') { return setTimeout(() => res.end(JSON.stringify({ code: 0, data: [] })), 3000); } if (type === 'error') { res.statusCode = 500; return res.end(JSON.stringify({ code: 500, message: 'mock server error' })); } res.end(JSON.stringify({ code: 0, data: [{ id: 1, name: 'ok' }] })); };
多人协作时怎么放 mock 数据?
团队共用 mock 不要散落在每个人的 Whistle 面板里,建议放进仓库并按业务目录组织。规则文件可以只写入口,mock 文件按接口域名或业务模块归档,例如 mock/user/profile.json、mock/order/list.js。这样评审时能直接看到字段变化,也方便后端一起确认返回结构。公共 mock 还可以配一份变更记录,说明字段新增、删除和默认值变化,避免旧页面继续依赖已经废弃的字段。规则文件只保留入口,具体 JSON 和脚本放在 mock/user、mock/order 之类的目录。每个 mock 文件最好说明对应接口、字段含义和适用场景,避免后端字段变了而 mock 还在误导前端。对于登录、权限、金额这类敏感链路,还要保留一份失败态样例,否则页面只在成功路径上好看,真实联调时很容易暴露遗漏。
追问
resBody 和 Values 应该怎么选?
短小、一次性的响应可以直接写 resBody,超过几行的 JSON 建议放 Values。取舍是内联写法最快,但可读性和复用性很差。边界是包含数组、嵌套对象或多人复用的数据,基本都应该拆成文件。踩坑是 JSON 里引号转义写错,规则看似保存成功,实际响应格式已经坏了。
什么时候必须用 resScript?
只要响应依赖请求参数、分页、登录态、时间或随机异常,就应该考虑 resScript。取舍是脚本更灵活,但也更像一段小服务,需要处理异常和维护逻辑。边界是不要在脚本里实现完整后端业务,否则 mock 会变成另一套难维护系统。踩坑是脚本返回字段和真实接口越来越不一致,前端在 mock 下正常,上测试环境马上报错。
要不要模拟失败和超时?
要,尤其是移动端弱网、权限过期、空数据这些用户很容易遇到的状态。取舍是多准备几套 mock 会增加工作量,但能提前发现 loading、重试、错误提示是否合理。边界是不要为了覆盖所有理论错误码而无限膨胀,优先模拟产品真的会展示差异的状态。踩坑是只测成功响应,结果接口 500 时页面白屏,直到上线前才发现。
mock 数据应该由前端还是后端维护?
初期可以由前端维护,因为前端最需要快速推进页面;接口稳定后最好和后端一起确认字段。取舍是前端维护速度快,后端确认准确性高。边界是涉及金额、权限、状态机的字段不能凭感觉编,必须和接口文档对齐。踩坑是 mock 里的枚举值写成了前端自创格式,后端真实返回后所有判断都失效。
复杂模拟要不要做成插件?
如果只是几个接口,resScript 已经够用;如果要统一管理大量场景、提供 UI 切换、记录请求,插件会更合适。取舍是插件体验更完整,但开发和发布成本更高。边界是团队复用、长期维护、需要状态管理时才值得插件化。踩坑是把简单 mock 过早做成插件,最后每次改一个字段都要发版,反而拖慢联调。