Mock 服务设计指南
本文档总结了一套经过实践验证的 Mock 服务设计方案适用于前端开发阶段的接口模拟具有模块化、可维护、真实业务逻辑等优势。1 设计初衷1.1 解决的问题问题传统 Mock 方案本方案前后端并行开发依赖后端接口完成前端可独立开发和调试接口变更成本多处修改 Mock 数据集中维护一处修改业务逻辑验证只能测试静态数据可验证状态流转、权限等逻辑联调效率频繁等待后端环境本地完整运行随时测试数据真实性随机数据缺乏关联生成符合业务规则的关联数据1.2 核心目标独立运行Mock 服务作为独立后端不侵入业务代码真实逻辑实现必要的业务规则状态流转、权限校验、数据关联易于维护模块化组织与业务接口一一对应快速切换通过环境变量或命令一键切换 Mock/真实模式2 架构设计2.1 整体架构┌─────────────────────────────────────────────────────────────┐ │ 前端应用 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 业务代码无 Mock 逻辑 │ │ │ │ - API 调用 │ │ │ │ - 状态管理 │ │ │ │ - UI 渲染 │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ │ HTTP 请求 ▼ ┌─────────────────────────────────────────────────────────────┐ │ 开发服务器Vite │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Proxy 配置 │ │ │ │ - /api/* → Mock 服务 或 真实后端 │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ┌───────────────┴───────────────┐ ▼ ▼ ┌─────────────────────────┐ ┌─────────────────────────┐ │ Mock 服务 │ │ 真实后端 │ │ - 独立端口如8082 │ │ - 测试/生产环境 │ │ - 内存数据存储 │ │ │ │ - 业务逻辑模拟 │ │ │ └─────────────────────────┘ └─────────────────────────┘2.2 目录结构project-root/ ├── src/# 业务代码纯净无 Mock 逻辑│ ├── api/# API 调用层│ ├── stores/# 状态管理│ ├── pages/# 页面组件│ └── components/# 公共组件│ ├── mock/# Mock 服务独立目录│ ├── server.ts# 服务入口│ ├── shared/# 共享工具│ │ ├── response.ts# 统一响应格式│ │ ├── types.ts# 共享类型定义│ │ └── utils.ts# 工具函数│ │ │ ├── module-a/# 业务模块 A│ │ ├── index.ts# 模块导出│ │ ├── routes.ts# 路由定义│ │ ├── store.ts# 数据存储│ │ ├── services.ts# 业务逻辑│ │ └── types.ts# 类型定义│ │ │ ├── module-b/# 业务模块 B│ │ └──... │ │ │ └── user/# 用户模块公共│ ├── routes.ts │ ├── users.ts# 预设用户数据│ └── types.ts │ ├── package.json# npm scripts├── vite.config.ts# Vite 配置proxy└── .env.mock# Mock 环境变量3 核心设计原则3.1 模块化组织原则每个业务模块独立目录与后端接口模块一一对应。// mock/incident/index.tsexport*from./routes;export*from./store;export*from./types;export{incidentRoutesasdefault}from./routes;优势职责清晰每个模块只负责自己的业务易于查找接口路径与目录结构对应独立演进模块间低耦合可独立修改3.2 统一响应格式原则所有接口使用统一的响应格式便于前端统一处理。// mock/shared/response.tsexportfunctionokT(data:T,extra:Recordstring,unknown{}){return{status:0,msg:ok,data,...extra,};}exportfunctionfail(message:string,status1){return{status,msg:message,data:null,};}响应格式{status:0,// 0成功非0失败msg:ok,// 提示信息data:{...},// 业务数据count:100,// 可选分页总数offset:0,// 可选偏移量size:20// 可选每页大小}3.3 内存数据存储原则使用内存对象存储 Mock 数据支持运行时增删改查。// mock/incident/store.tsexportconstincidentStore{incidentSeq:1,incidents:createInitialIncidents(),// 初始化时生成};// 初始化数据functioncreateInitialIncidents():MockIncidentPayload[]{returnArray.from({length:100},(_,index)createIncident(index1));}// 数据操作函数exportfunctionappendIncident(incident:MockIncidentPayload){incidentStore.incidents.unshift(incident);}exportfunctionfindIncidentById(id:number){returnincidentStore.incidents.find(itemitem.idid);}优势数据可变支持真实的增删改查操作状态一致所有接口共享同一份数据生命周期服务重启时重置保证干净状态3.4 业务逻辑模拟原则在 Mock 服务中实现关键业务逻辑而非只返回静态数据。// 状态流转逻辑exportfunctioneditIncidentStatus(incident:MockIncidentPayload,newStatus:number){constvalidTransitions:Recordnumber,number[]{1:[2,3],// 待确认 → 处理中、已驳回2:[4,5],// 处理中 → 已解决、已关闭4:[6],// 已解决 → 已关闭5:[2],// 已关闭 → 处理中重新打开};constallowedvalidTransitions[incident.status]||[];if(!allowed.includes(newStatus)){return不允许从状态${incident.status}转换到${newStatus};}incident.statusnewStatus;incident.updated_atMath.floor(Date.now()/1000);returnnull;// 成功}模拟的业务逻辑类型状态流转数据状态变更规则权限校验操作权限、数据权限数据校验必填字段、格式校验关联操作级联更新、触发事件3.5 类型安全原则完整的 TypeScript 类型定义与后端接口文档对齐。// mock/incident/types.tsexporttypeMockIncidentPayload{id:number;incident_id:string;event_title:string;status:number;created_at:number;updated_at:number;// ... 其他字段};优势编译时检查字段名、类型错误在开发时发现智能提示IDE 自动补全提高开发效率文档即代码类型定义即接口文档4 数据生成策略4.1 初始数据生成原则使用确定性算法生成初始数据保证可重现。functioncreateIncident(sequence:number):MockIncidentPayload{// 使用 sequence 作为种子保证每次生成相同数据constcreatorpickOne(mockUsers,sequence-1);conststatuspickOne([1,1,1,2,3,4,5,6,7,7,8],sequence);consteventCategorypickOne([S0,S1,S2,S3,S4,S5],sequence);return{id:sequence,incident_id:INC-2026-${String(sequence).padStart(4,0)},status,event_category:eventCategory,// ...};}4.2 边界场景覆盖原则初始数据中包含特殊场景用于验证边界情况。functioncreateInitialIncidents(){constincidentsArray.from({length:100},(_,index)createIncident(index1));// 特殊场景 1待补充状态incidents[0]{...incidents[0],system_list:[{id:pending-system,name:待补充系统}],};// 特殊场景 2空状态验证incidents[1]{...incidents[1],event_title:暂无空状态样式,mock_no_operation_audit:true,};// 特殊场景 3大数据量验证incidents[2]{...incidents[2],event_title:1000 条操作,mock_operation_audit_count:1000,};returnincidents;}4.3 数据关联原则维护数据间的关联关系保证查询结果真实。// 数据与评价关联exportfunctiongetEvaluationStatistics(){constallEvaluationsincidentStore.incidents.flatMap(incidentincident.evaluations.map(evaluation({id:evaluation.id,incident_id:incident.incident_id,incident_name:incident.event_title,score:evaluation.score,// ...})));return{score_counts:[1,2,3,4,5].map(score({score,count:allEvaluations.filter(ee.scorescore).length,})),total:allEvaluations.length,evaluations:allEvaluations,};}5 路由设计5.1 路由定义原则使用声明式定义路由与后端接口路径一致。// mock/incident/routes.tsexportconstincidentRoutes:MockMethod[][{url:/api/v1/incident/list,method:get,response(this:RespThisType,input:MockRequestInput){constpagelistIncidentPage(input);returnok(page.data,{count:page.count},input,this.res);},},{url:/api/v1/incident/add,method:post,response(this:RespThisType,input:MockRequestInput){constincidentcreateMockIncident(input.body);appendIncident(incident);returnok({id:incident.id},{},input,this.res);},},// ...];5.2 请求参数处理原则统一处理查询参数和请求体。// mock/shared/response.tsexportfunctiongetTextParam(query:Recordstring,unknown,key:string){constvaluequery[key]??query[${key}[]];if(Array.isArray(value))returnString(value[0]||).trim();returnString(value||).trim();}exportfunctiongetNumberParam(query:Recordstring,unknown,key:string){consttextgetTextParam(query,key);if(!text)returnundefined;constparsedNumber(text);returnNumber.isFinite(parsed)?parsed:undefined;}5.3 错误处理原则返回明确的错误信息便于前端展示。{url:/api/v1/incident/edit,method:put,response(this:RespThisType,input:MockRequestInput){constincidentfindIncidentById(input.body.id);if(!incident){returnfail(数据不存在,404,input,this.res);}if(incident.status4){returnfail(已关闭的数据不可编辑,400,input,this.res);}patchIncident(incident,input.body);returnok({id:incident.id},{},input,this.res);},},6 用户与权限模拟6.1 预设用户原则预设多个用户角色便于测试不同权限场景。// mock/user/users.tsexportconstmockUsers:MockUserPayload[][{uid:u10001,name:张三,personaKey:admin,resources:[uatu.evaluation,uatu.edit,uatu.close],},{uid:u10002,name:李四,personaKey:operator,resources:[uatu.edit],},{uid:u10003,name:王五,personaKey:viewer,resources:[],},];6.2 用户切换原则支持运行时切换用户身份便于测试权限逻辑。// mock/user/routes.ts{url:/api/v2/user/self,method:get,response(this:RespThisType,input:MockRequestInput){// 从 Cookie 或 Header 读取当前用户constusergetMockUserByCookie(input.headers);returnok({uid:user.uid,name:user.name,resources:user.resources,},{},input,this.res);},},7 与前端集成7.1 Vite 配置原则通过 Proxy 将请求转发到 Mock 服务业务代码无需感知。// vite.config.tsexportdefaultdefineConfig(({mode}){constenvloadEnv(mode,__dirname,VITE_);constisMockModeenv.VITE_APP_MODEmock;return{server:{proxy:isMockMode?{/api/:{target:http://localhost:8082,changeOrigin:true,},}:{/api/:{target:env.VITE_API_SERVER_HOST,changeOrigin:true,},},},};});7.2 环境变量原则通过环境变量控制 Mock 模式业务代码不依赖 Mock 逻辑。# .env.mockVITE_APP_MODEmockVITE_API_BASE_URL/api# .env.developmentVITE_APP_MODEproxyVITE_API_SERVER_HOSThttps://api-dev.example.com# .env.productionVITE_APP_MODEapiVITE_API_SERVER_HOSThttps://api.example.com7.3 npm scripts{scripts:{dev:vite,mock:node mock/server.js,dev:mock:concurrently \npm run mock\ \vite --mode mock\}}8 脱敏与安全8.1 数据脱敏原则Mock 数据不包含真实业务数据使用虚构数据。// ✅ 正确使用虚构数据constmockUsers[{uid:u10001,name:张三},{uid:u10002,name:李四},];// ❌ 错误使用真实数据constrealUsers[{uid:EMP2024001,name:真实姓名},];8.2 接口路径通用化原则移除项目特定的路径前缀使用通用路径。// 原始路径项目特定url:/xxx/api/v1/incident/list// 通用化路径url:/api/v1/incident/list8.3 配置外部化原则将可变配置提取到环境变量或配置文件。// 不硬编码使用环境变量constAPI_PREFIXprocess.env.API_PREFIX||/api;constMOCK_PORTprocess.env.MOCK_PORT||8082;9 最佳实践9.1 命名规范类型规范示例目录名kebab-caseincident/、major-event/文件名kebab-caseroutes.ts、store.ts类型名PascalCase PayloadMockIncidentPayload函数名camelCasecreateMockIncident()常量名UPPER_SNAKE_CASEMOCK_PORT9.2 文件职责文件职责内容routes.ts路由定义URL、Method、Responsestore.ts数据存储内存对象、CRUD 操作services.ts业务逻辑状态流转、权限校验types.ts类型定义接口类型、请求/响应类型index.ts模块导出统一导出入口9.3 开发流程定义类型先写types.ts明确接口契约实现存储编写store.ts定义数据结构和 CRUD编写路由编写routes.ts实现接口添加逻辑如需业务逻辑编写services.ts测试验证启动 Mock 服务前端调用验证9.4 常见陷阱陷阱正确做法Mock 数据写死使用算法生成保证可重现业务代码依赖 Mock业务代码只调用接口不判断环境Mock 逻辑过于复杂只模拟关键业务逻辑不追求 100% 覆盖忘记重置数据服务重启时自动重置或提供重置接口10 扩展能力10.1 延迟模拟// 模拟网络延迟{url:/api/v1/incident/list,method:get,response:async(input){awaitnewPromise(resolvesetTimeout(resolve,300));returnok(data);},}10.2 错误注入// 模拟随机失败{url:/api/v1/incident/add,method:post,response:(input){if(Math.random()0.1){returnfail(服务器内部错误,500);}returnok(data);},}10.3 数据持久化// 可选将数据持久化到文件importfsfromfs;constDATA_FILE./mock-data.json;functionloadData(){if(fs.existsSync(DATA_FILE)){returnJSON.parse(fs.readFileSync(DATA_FILE,utf-8));}returncreateInitialData();}functionsaveData(data:unknown){fs.writeFileSync(DATA_FILE,JSON.stringify(data,null,2));}11 适用场景11.1 适用前后端并行开发接口契约已确定需要验证业务逻辑演示和培训环境11.2 不适用接口契约未确定先定义接口简单的 CRUD直接用 json-server性能测试使用专业工具12 总结本方案的核心优势独立性Mock 服务独立运行不侵入业务代码真实性模拟业务逻辑可验证状态流转可维护性模块化组织易于扩展和修改类型安全TypeScript 类型定义编译时检查数据关联维护数据间关系查询结果真实适用团队规模3-20 人前端团队项目周期 3 个月以上。

相关新闻

2026年数据工程师就业趋势与核心技能解析

2026年数据工程师就业趋势与核心技能解析

1. 蒸汽教育求职分享:2026年数据工程师就业优势分析数据工程师(Data Engineer)这个岗位在2023-2024年已经成为了技术招聘市场的香饽饽,而根据LinkedIn最新发布的《2025年新兴就业报告》预测,到2026年数据工程师的需求量…

2026/10/14 20:48:02 阅读更多 →
2026最新:录音怎么转文字哪个好?3款亲测免费实用神器职场必备

2026最新:录音怎么转文字哪个好?3款亲测免费实用神器职场必备

先说明白核心判断 针对职场新人的入职培训记录、产品知识学习、技能入门记录需求,本次2026年最新亲测的3款免费录音转文字工具中,不同需求对应不同选择:需要多语言转写可以选Sonix,阿里云生态日常办公用户可以选通义听悟&#xf…

2026/10/5 19:23:37 阅读更多 →
2026年访谈录音转文字推荐,新手怎么选才适配访谈需求?

2026年访谈录音转文字推荐,新手怎么选才适配访谈需求?

先回答用户真正关心的问题 2026年选访谈录音转文字工具,新手不用盲目追大而全,核心要匹配访谈整理的核心需求:转写准确、能直接出可用的整理框架,方便导出复用成干货内容。对需要把访谈内容转化为付费课程的新手来说,…

2026/10/14 9:01:08 阅读更多 →

最新新闻

yolov8-face 核心算子全解析:NMS、边界框格式转换与掩码处理的源码级指南

yolov8-face 核心算子全解析:NMS、边界框格式转换与掩码处理的源码级指南

人工智能计算机视觉深度学习 【免费下载链接】yolov8-face yolov8 face detection with landmark 项目地址: https://gitcode.com/gh_mirrors/yo/yolov8-face 点击查看 免费下载 本文是 ops.md 参考文档的深度展开,以 ultralytics/yolo/utils/ops.py 为…

2026/10/14 20:49:14 阅读更多 →
自学嵌入式第二天(C语言篇——数据类型)

自学嵌入式第二天(C语言篇——数据类型)

琐碎的敲代码内功。(以为很简单 ,结果全是坑)1.C语言提供的数据类型2.整数类型常量:在程序运行过程中,其值不能被改变的量变量:在程序运行过程中,其值能被改变的量(1)整型…

2026/10/14 20:49:14 阅读更多 →
openJiuwen 记忆引擎基础模型:MemInfo 单条记忆信息结构全解

openJiuwen 记忆引擎基础模型:MemInfo 单条记忆信息结构全解

人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习 【免费下载链接】agent-core-java openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。 项目地址: https://gitco…

2026/10/14 20:49:14 阅读更多 →
模拟退火求解二维装箱问题:原理、实现与工程调优

模拟退火求解二维装箱问题:原理、实现与工程调优

模拟退火算法求解装箱问题,我第一次真正上手,是在一个托盘排样项目里。需求方只说了一句话:把尺寸不一的纸箱尽量多地放进托盘,允许90度旋转,不许压坏。我当时觉得,这就是矩形排样,先求个面积下…

2026/10/14 20:49:14 阅读更多 →
51单片机DHT11温湿度采集实战:从仿真到实物的完整拆解

51单片机DHT11温湿度采集实战:从仿真到实物的完整拆解

简介:一套以51单片机为核心的温湿度采集监控完整工程,面向电子爱好者、嵌入式初学者及课程设计学生。资料基于Keil平台,由C语言编写,实现温湿度采集(SHT10传感器)、日历时钟(DS1302)…

2026/10/14 20:49:14 阅读更多 →
Towards Automated Regulatory Compliance Verification in Financial Auditing with Large Language Mo...

Towards Automated Regulatory Compliance Verification in Financial Auditing with Large Language Mo...

文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现财务审计中监管合规性的自动验证,旨在解决传统审计中人工验证合规性的低效问题。研究对比了开源LLMs(如Llama-2系列)与专有LLMs(如OpenAI的GPT系列)在合规性检测中的性能,使用了普华永道(PwC)提供的两个自定义…

2026/10/14 20:48:13 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →