109 KiB
HTTP Client 应用程序实施计划
项目概述
创建一个类似 IntelliJ IDEA HTTP Client 的 BS 架构应用程序,支持 .http 文件解析和执行。
核心兼容范围
项目目标为:完整兼容 IntelliJ IDEA HTTP Client 的核心使用方式,产品目标版本以“全部支持”为目标,不做语法子集裁剪。
兼容范围包括但不限于:
-
支持标准
.http/.rest文件解析 -
支持单文件内多个请求块及
###分隔语法 -
支持请求命名、请求注释、请求描述信息展示
-
支持全部常见 HTTP 方法及自定义方法
-
支持 URL、Header、Query、Body 中的变量引用与替换
-
支持环境变量、全局变量、文件内变量及变量覆盖规则
-
支持 JSON、XML、Text、Form URL Encoded、Multipart Form Data、二进制文件等请求体类型
-
支持引用外部文件作为请求体或表单字段内容
-
支持 Cookie、重定向、代理、超时、SSL/TLS、客户端证书等常见请求配置
-
支持响应结果查看、Header/Cookie 展示、格式化预览、响应时间与大小统计
-
支持请求前置脚本、请求后置脚本、断言、链式请求、响应数据提取与变量回填
-
支持从当前光标位置识别并执行当前请求,行为与 IntelliJ IDEA HTTP Client 保持一致
-
支持常见语法错误提示,并尽可能与 IntelliJ IDEA HTTP Client 的解析行为保持一致
-
支持导出 curl、导入常见 HTTP 请求定义,尽量保持与原始请求语义一致
-
支持导入 OpenAPI 3.0 / 3.1 契约文件,并生成
.http请求模板、Mock 规则骨架和响应 Schema 校验能力
兼容性要求:
-
功能设计优先遵循 IntelliJ IDEA HTTP Client 的行为模型,新增自定义语法前必须保证不破坏原有兼容性
-
若遇到 IntelliJ IDEA HTTP Client 的边界语法或特殊行为,应以兼容为第一原则,不以“简化实现”为理由降级支持
-
所有解析器、执行器、前端交互设计均需以兼容性测试用例驱动,建立覆盖常见语法与边界场景的回归测试集
-
发布前需使用真实
.http示例文件进行兼容性验收,确保常用工作流可直接迁移
兼容矩阵要求
-
文档需维护一份可持续更新的 IntelliJ IDEA HTTP Client 兼容矩阵,按“语法项 / 是否支持 / 差异说明 / 测试用例”逐项列出
-
兼容矩阵至少覆盖:请求分隔、请求命名、注释、变量声明与引用、环境文件、脚本块、断言、文件引用、multipart、重定向、Cookie、SSE、WebSocket、curl 导出、Postman 导入、OpenAPI 导入
-
对于暂未完全一致的行为,必须在兼容矩阵中记录具体差异、影响范围和回归用例,不能只写“部分支持”
解析器 AST 约束
-
.http/.rest解析器需输出稳定 AST,不直接将文本解析结果绑定到执行器内部结构 -
AST 至少包含:文件、请求块、注释、请求名称、方法、URL、Header、Body、变量引用、脚本块、断言块、源代码位置
-
AST 节点必须保留
range信息,至少包含起始行列、结束行列、起始 offset、结束 offset -
AST 需支持错误恢复;单个请求块解析失败时,不应阻断同文件其他请求块的识别
-
前端当前请求定位、语法高亮、错误标记、变量预览应尽量复用后端 AST 或等价结构,避免前后端各自实现不一致的解析逻辑
-
解析器输出需可序列化为 JSON,用于 API 调试、测试快照与前端辅助展示
需求追踪与决策记录
-
需求、任务、测试和验收需建立可追踪关系,避免实现阶段出现“做了功能但找不到验收依据”的情况
-
核心需求建议使用稳定编号,例如
REQ-CORE-*、REQ-FILE-*、REQ-EXEC-*、REQ-MOCK-*、REQ-OPENAPI-*、REQ-LOAD-*、REQ-UI-* -
MVP 任务编号需能映射到至少一个需求编号和至少一个测试或验收项
-
兼容矩阵中的每一项都应具备对应 fixture 或测试用例路径,不能只停留在文档描述
-
产品目标版本增强项如果暂未进入 MVP,需在矩阵或实施阶段中明确归属,避免被误判为 MVP 缺失
-
关键架构决策需记录为 ADR,默认路径为
docs/decisions/ADR-{number}-{topic}.md -
ADR 至少记录:状态、背景、决策、备选方案、影响范围、后续迁移成本
-
已确定的关键决策至少包括:纯 Go 本地服务 + 浏览器前端、REST 控制面 + WebSocket 事件流、SQLite 仅做索引/缓存/命中日志、工作区文件作为事实源
-
若后续需求与已记录 ADR 冲突,应先更新 ADR 和影响说明,再修改实现计划
技术栈
-
后端: Go (Gin 框架)
-
前端: Vue 3 + TypeScript + Vite
-
本地集成: 原生 Go + 系统托盘库 (systray)
-
HTTP 解析: Go 自定义 .http 文件解析器
-
架构: 本地 Go 服务 + 浏览器前端,后端提供 Web 服务与静态资源托管
项目结构
api-client/
├── backend/
│ ├── cmd/api-client/ # 本地服务入口
│ ├── internal/api/ # REST API 与 WebSocket handler
│ ├── internal/app/ # 应用启动、依赖装配、生命周期管理
│ ├── internal/parser/ # .http / .rest 解析器与 AST
│ ├── internal/workspace/ # 工作区模型、文件扫描、路径解析
│ ├── internal/filestore/ # 原子写入、contentHash、外部变更检测
│ ├── internal/execution/ # Execution 状态机、调度、结果固化
│ ├── internal/eventbus/ # 实时事件、重放、背压与订阅管理
│ ├── internal/runtime/ # JavaScript 脚本运行时与内置 API
│ ├── internal/httpclient/ # HTTP 请求发送、TLS、代理、Cookie
│ ├── internal/mock/ # Mock Server、规则匹配、命中日志
│ ├── internal/openapi/ # OpenAPI 导入、同步、diff、Schema 校验
│ ├── internal/cacheindex/ # SQLite 索引、缓存索引、迁移
│ ├── internal/tray/ # 系统托盘与单实例协作
│ └── internal/model/ # 跨模块共享模型与错误码
├── frontend/
│ ├── src/app/ # 应用入口、路由、全局状态装配
│ ├── src/shared/ # 通用组件、工具、API client、类型
│ ├── src/features/editor/ # 请求编辑器、当前请求定位、变量预览
│ ├── src/features/response/ # 响应查看、流式渲染、Schema 校验结果
│ ├── src/features/history/ # 历史列表与详情
│ ├── src/features/environment/# 环境管理
│ ├── src/features/mock/ # Mock 管理页
│ ├── src/features/openapi/ # OpenAPI 管理页
│ ├── src/features/loadtest/ # 压测配置与报告
│ └── public/
├── contracts/ # 本应用 REST API OpenAPI 契约与生成配置
├── fixtures/ # 测试夹具与快照
├── scripts/ # 构建、生成、校验脚本
└── build/ # 打包输出与安装资源
后端模块边界
-
api仅负责 HTTP handler、参数绑定、响应 envelope 与错误映射,不直接读写工作区文件或 SQLite -
parser仅负责.http/.rest文本到 AST 的解析、错误恢复和源位置映射,不负责变量替换和请求发送 -
workspace负责工作区根目录、相对路径、符号链接解析、文件扫描和最近文件来源抽象 -
filestore负责文件读取、原子写入、contentHash、外部变更检测、文件版本,不理解 Mock、OpenAPI 或环境变量业务语义 -
execution负责 Execution 生命周期、队列调度、取消、超时、父子任务、结果固化,不直接实现具体 HTTP transport -
eventbus负责事件发布、订阅、序号、重放、背压和 WebSocket fan-out,不包含业务执行逻辑 -
runtime负责 JavaScript 运行时、脚本上下文、内置 API 和脚本超时,不直接访问浏览器环境 -
httpclient负责最终 HTTP 请求发送、连接复用、TLS、代理、Cookie、重定向和响应流读取 -
mock负责 Mock Server、规则加载、匹配、模板渲染、代理回退和命中日志;规则事实源仍通过filestore写入.mock.json -
openapi负责目标接口 OpenAPI 文件解析、导入预览、同步 diff、请求模板生成、Mock 骨架生成和 Schema 校验 -
cacheindex负责 SQLite schema、索引重建、缓存记录、迁移和保留策略,不保存工作区事实源数据 -
tray仅负责系统托盘、单实例唤起、打开浏览器和退出服务,不持有业务状态
前端模块边界
-
shared/api负责统一 REST client、WebSocket client、请求 envelope、错误码类型和重试策略 -
features/editor负责文件编辑、语法高亮、当前请求定位、请求块操作和变量预览 -
features/response负责普通响应、流式响应、SSE / WebSocket 会话视图、Schema 校验结果和大响应分段渲染 -
features/history负责历史列表、历史详情、重新执行、打开源文件和定位请求块 -
features/environment负责环境变量文件的展示、编辑、导入导出和默认环境选择 -
features/mock负责 Mock Server 状态、规则编辑、优先级排序、命中日志和规则文件保存重载 -
features/openapi负责 OpenAPI 源列表、导入向导、同步预览、diff 视图和生成目标选择 -
features/loadtest负责压测配置、实时指标、报告展示和采样明细,不直接调普通执行接口模拟压测 -
前端不得重复实现
.http完整解析器;当前请求定位、错误标记和变量预览应优先消费后端 AST 或后端等价解析结果
文件管理约束
-
.http/.rest文件以本地工作区文件形式管理,不存入数据库 -
应用负责本地文件的打开、保存、另存为、最近文件记录与目录浏览
-
应用负责检测文件外部变更,并提示用户重新加载或保留当前未保存内容
-
应用不提供应用内三方合并或冲突解决界面
-
文件冲突统一通过
Git同步、合并与解决,应用仅提供必要的变更提示 -
请求历史索引可存入 SQLite;环境变量与项目配置以工作区 JSON 文件为准;原始
.http文件内容仍以本地文件为准 -
环境变量、项目配置、Mock 规则等可版本管理数据默认保存为工作区文件,文件冲突统一通过 Git 处理
-
OpenAPI 契约文件默认以本地工作区文件形式管理,应用可读取、导入、同步和生成派生产物,但不将原始 OpenAPI 内容写入 SQLite
文件写入一致性
-
所有工作区事实源文件保存均需采用原子写入:先写入同目录临时文件,校验成功后再执行原子替换
-
文件保存失败时不得破坏原文件;失败后需保留可理解错误,并尽量清理临时文件
-
文件保存请求需携带
baseVersion或contentHash,用于检测保存期间的外部变更 -
若保存时发现目标文件已被外部修改,应用不得静默覆盖,需提示用户重新加载、另存为或交给 Git 合并
-
.http-client/environments.json、.http-client/settings.json、.http-client/mocks/**/*.mock.json均需遵循同一套原子写入和冲突检测规则 -
.http-client/openapi/sources.json需遵循同一套原子写入和冲突检测规则,用于保存 OpenAPI 源文件映射与同步配置
文本编码与格式约束
-
工作区事实源文本文件默认使用
UTF-8编码保存 -
读取
.http/.rest文件时应兼容带 BOM 的 UTF-8 文件,保存时默认不主动添加 BOM -
文件保存时应尽量保持原文件换行风格;新建文件默认使用
LF -
.http-client/*.json文件保存时需使用稳定缩进,默认2个空格,并保持字段顺序稳定,减少 Git diff 噪音 -
JSON 文件不得写入注释;若需要备注说明,应使用显式字段,例如
description -
生成的
.http文件需包含来源注释和更新时间,但不得写入机器本地绝对路径,避免多人协作时产生无意义 diff -
二进制响应体、Mock 静态资源和缓存文件不得被误判为文本文件进行格式化
工作区配置 Schema
-
.http-client/environments.json、.http-client/settings.json、.http-client/mocks/**/*.mock.json、.http-client/openapi/sources.json均需具备明确schemaVersion -
工作区 JSON 文件需具备对应 JSON Schema 草案,默认保存到
contracts/workspace-json-schemas/ -
应用保存工作区 JSON 前必须执行基础 schema 校验,失败时不得覆盖原文件
-
应用读取高版本
schemaVersion文件时,默认只读或拒绝写入,并提示当前应用版本不支持该 schema -
应用读取低版本
schemaVersion文件时,可执行自动迁移;迁移前必须备份原文件 -
JSON Schema 需覆盖必填字段、枚举值、默认值、路径字段格式和数组元素结构
-
测试夹具中的工作区 JSON 文件需通过 schema 校验,防止示例与真实格式漂移
工作区模型
-
应用以“工作区目录”为主要操作单位,同时支持直接打开单个
.http/.rest文件 -
当用户直接打开单个文件时,应自动以该文件所在目录作为临时工作区根目录
-
相对路径解析默认以当前请求文件所在目录为第一基准,以当前工作区根目录为第二基准
-
文件引用、脚本引用、外部请求体引用均需明确遵循统一的相对路径解析规则
-
MVP 阶段支持单工作区模型;多工作区并行打开不纳入当前范围
-
是否允许访问工作区外文件需提供明确配置项,默认允许用户显式选择工作区外文件,但界面需给出路径提示
-
若遇到符号链接、快捷方式或软链接路径,应统一解析到真实路径后再执行文件访问与变更检测
文件监听与增量索引
-
后端需提供工作区文件监听能力,监听范围至少覆盖已打开的
.http/.rest文件、.http-client/environments.json、.http-client/settings.json、.http-client/mocks/**/*.mock.json、.http-client/openapi/sources.json和已登记 OpenAPI 源文件 -
文件监听事件需做去抖处理,默认去抖窗口为
300ms,避免保存过程中的多次底层事件触发重复解析和重复提示 -
文件监听不应直接覆盖编辑器内容;若当前文件存在未保存修改,仅提示外部变更并提供重新加载入口
-
外部文件变更后应优先执行增量索引:单个
.http文件变更仅重建该文件 AST 与请求索引,单个.mock.json变更仅重建对应 Mock 规则索引,单个 OpenAPI 源变更仅重建对应 source 与 operation 索引 -
若增量索引失败,需记录错误摘要并允许用户触发全量
POST /api/indexes/rebuild -
Git 分支切换、批量拉取、批量替换等可能产生大量文件变更时,应用应合并通知为一次“工作区发生大量变更”提示,并建议重建索引
-
文件监听可按平台差异采用不同底层实现,但对上层统一输出:
created、updated、deleted、renamed、unknown五类事件
本地服务与执行模型
本地服务约束
-
应用以后端本地服务形式运行,前端通过浏览器访问本地页面
-
本地服务负责提供 API、事件通道、静态资源托管、文件访问与执行调度能力
-
本地服务默认单实例运行,重复启动时应复用已有实例并直接打开应用页面
-
本地服务启动后默认自动打开浏览器页面,用户关闭浏览器后服务可继续驻留后台
-
首次启动时若默认端口被占用,应自动选择可用端口并更新应用页面打开地址
-
若检测到已有本应用实例正在运行,则始终复用该实例,不再新开服务进程或重新选择端口
本地服务启动协议
-
默认监听地址为
127.0.0.1 -
默认端口为
32180 -
若默认端口不可用,端口探测范围为
32181-32200 -
浏览器打开地址格式为
http://127.0.0.1:{port}/ -
单实例发现优先使用本地锁文件与端口探测结合的方式
-
服务启动成功后需写入运行时元信息文件,至少包含端口、进程 ID、启动时间、数据目录
执行模型总览
-
所有请求执行统一抽象为
Execution -
前端发起执行时,后端先创建执行任务并返回
executionId,不直接以同步接口返回完整响应 -
REST API 负责执行创建、执行查询、执行取消、历史查询、文件管理、环境管理等控制面能力
-
WebSocket 负责执行过程中的实时事件推送,包括状态变化、流式响应、脚本日志、断言结果、最终完成事件
-
单请求、批量请求、链式请求、SSE、WebSocket 会话、压测执行均复用同一套执行模型
Execution 类型
-
http: 单次 HTTP 请求执行 -
batch: 批量请求执行,包含多个子执行任务 -
chain: 链式请求执行,后续步骤可依赖前序步骤变量提取结果 -
sse: Server-Sent Events 长连接执行 -
websocket: WebSocket 会话执行 -
load-test: 对目标接口发起轻量压测执行 -
mock-server: 本地 Mock Server 运行任务
Execution 状态机
-
pending: 任务已创建,等待调度 -
running: 任务已进入解析、变量替换、脚本执行、请求发送等阶段 -
streaming: 已开始持续接收响应内容或实时消息 -
completed: 执行成功结束,最终结果已固化 -
failed: 执行失败,包括解析失败、脚本失败、请求失败、断言失败等 -
cancelled: 执行被用户主动取消或被父任务取消 -
状态流转至少支持:
pending -> running -> completed/failed/cancelled,以及running -> streaming -> completed/failed/cancelled
REST API 设计
-
POST /api/executions: 创建执行任务,返回executionId -
GET /api/executions/:id: 查询执行状态、当前阶段、开始时间、结束时间、错误摘要 -
POST /api/executions/:id/cancel: 取消执行任务 -
GET /api/executions/:id/result: 获取最终结果快照,用于页面刷新恢复与历史回看 -
GET /api/history: 分页查询执行历史 -
GET /api/history/:id: 查询历史执行详情 -
GET /api/events/ws: 建立全局 WebSocket 事件通道 -
GET /api/files/*: 本地文件与工作区读取接口 -
POST /api/files/save: 文件保存接口 -
GET /api/environments: 环境列表与变量读取接口 -
POST /api/environments: 环境创建或更新接口 -
GET /api/mocks: 查询当前工作区 Mock 规则列表 -
POST /api/mocks: 创建或更新 Mock 规则,并写回对应 Mock 规则文件 -
DELETE /api/mocks/:id: 删除 Mock 规则,并写回对应 Mock 规则文件 -
GET /api/mock-files: 查询当前工作区 Mock 规则文件列表 -
POST /api/mock-files/save: 保存当前工作区 Mock 规则文件 -
POST /api/mock-files/reload: 从工作区 Mock 规则文件重新加载并重建索引 -
POST /api/mock-files/preview: 预览 Mock 规则文件变更,返回新增、更新、冲突、跳过数量 -
POST /api/mock-server/start: 启动当前工作区 Mock Server -
POST /api/mock-server/stop: 停止当前工作区 Mock Server -
GET /api/mock-server/status: 查询 Mock Server 状态 -
GET /api/mock-server/hit-logs: 分页查询 Mock Server 命中日志 -
DELETE /api/mock-server/hit-logs: 清空当前工作区 Mock Server 命中日志 -
GET /api/openapi/sources: 查询当前工作区已登记的 OpenAPI 契约源列表 -
POST /api/openapi/import: 导入 OpenAPI 文件并生成.http请求模板、Mock 规则骨架、Schema 校验映射的预览结果 -
POST /api/openapi/sync/preview: 基于已登记 OpenAPI 契约源预览同步变更,返回新增、更新、删除、冲突和不可映射项 -
POST /api/openapi/sync/apply: 应用用户确认后的 OpenAPI 同步变更,并写入对应工作区文件 -
POST /api/openapi/diff: 对比两个 OpenAPI 契约文件,返回接口、参数、请求体、响应 Schema 的变更摘要 -
POST /api/openapi/validate-response: 使用 OpenAPI 响应 Schema 校验某次执行结果或用户粘贴的响应样本 -
POST /api/indexes/rebuild: 重建当前工作区 SQLite 索引与缓存索引
API JSON 合同
-
所有 REST API 响应统一包含:
success、data、error、requestId、timestamp -
成功响应中
success=true,error=null;失败响应中success=false,data=null -
错误对象至少包含:
code、message、details、location -
分页查询接口统一使用:
page、pageSize、total、items -
POST /api/executions响应至少包含:executionId、status、type -
GET /api/executions/:id响应至少包含:executionId、status、type、stage、startedAt、finishedAt、error -
GET /api/executions/:id/result响应至少包含完整ExecutionResult -
GET /api/history响应项至少包含:executionId、type、status、requestName、filePath、environment、durationMs、startedAt -
WebSocket 事件统一采用 envelope 结构:
type、executionId、seq、timestamp、payload -
REST API 示例、OpenAPI 契约与测试快照必须统一使用响应 envelope,不允许同一接口同时存在裸对象响应与 envelope 响应
-
写入类接口需支持幂等请求标识,推荐使用
Idempotency-KeyHeader 或请求体operationId -
POST /api/executions/:id/cancel、POST /api/mock-files/reload、POST /api/indexes/rebuild必须具备幂等语义,重复调用不得产生不一致状态 -
文件保存类接口需在请求体中携带
baseVersion或contentHash,并在冲突时返回FILE_CONFLICT -
规则级写入接口(如
POST /api/mocks、DELETE /api/mocks/:id)需通过显式filePath或mock_rule_index定位目标规则文件,并复用同一套contentHash冲突检测
API 类型与契约生成
-
后端需维护 API 契约源,推荐使用 OpenAPI 3.1 或等价 JSON Schema 描述 REST 接口
-
前端 TypeScript API 类型应由 API 契约生成,避免手写重复类型
-
WebSocket 事件 envelope 与 payload 类型需纳入同一契约体系,至少提供 TypeScript 类型定义
-
CI 或测试流程需校验 API 契约与示例 JSON 的基本一致性
-
破坏性 API 变更需在文档中记录迁移说明
内部 API 契约落地
-
本应用自身 REST API 契约默认保存为
contracts/app-api.openapi.yaml -
WebSocket 事件 payload 类型默认保存为
contracts/events.schema.json或在contracts/app-api.openapi.yaml的components.schemas中统一声明 -
前端 API 类型、请求参数类型、响应 envelope 类型必须从契约生成,生成目录默认为
frontend/src/shared/api/generated/ -
后端 handler 层可使用契约校验工具或快照测试校验响应结构,避免文档、示例和实现漂移
-
生成代码不得手工编辑;如需改类型,应修改契约源并重新生成
-
CI 至少执行契约格式校验、示例 JSON 快照校验和前端类型生成校验
-
契约变更需在 PR 或变更说明中标记为兼容变更或破坏性变更,并说明前端影响范围
目标接口 OpenAPI 文件支持
-
需明确区分两类 OpenAPI:本应用自身 REST API 的 OpenAPI 契约用于前后端类型生成;用户导入的目标接口 OpenAPI 文件用于生成请求、Mock、Schema 校验和变更对比
-
用户导入的 OpenAPI 文件定位为“接口契约来源”,不替代
.http/.rest文件;.http/.rest仍是实际调试、执行、脚本、断言和链式场景的主要载体 -
支持导入本地
openapi.yaml、openapi.yml、openapi.json文件,产品目标版本支持 OpenAPI 3.0 与 3.1 -
OpenAPI 导入需解析
paths、operationId、tags、parameters、requestBody、responses、security的基础结构;security字段暂不展开执行能力,仅保留为导入报告中的不可执行配置提示 -
导入后默认按
tags或路径前缀生成请求分组,并生成可读的.http请求模板 -
.http请求模板需保留 OpenAPI 来源信息,至少包含sourceId、operationId、method、path、schemaRef,用于后续同步定位 -
OpenAPI 变量映射默认将
servers[0].url映射为{{baseUrl}},并允许用户在导入预览中修改目标环境变量名 -
OpenAPI
parameters需映射为 Query、Path、Header、Cookie 的请求模板占位符;必填参数需在模板中明显标记 -
OpenAPI
requestBody需根据content-type生成 JSON、Form、Multipart 或 Raw Body 示例;多个示例存在时优先使用examples,其次使用example,最后根据 Schema 生成基础样例 -
OpenAPI
responses需用于生成响应 Schema 校验映射,并可用于生成基础 Mock 响应骨架 -
OpenAPI 导入不得静默覆盖已有
.http、Mock 规则或配置文件;所有写入前必须展示预览与冲突列表 -
OpenAPI 同步需支持只新增、更新已有生成块、跳过本地已修改块三种策略;默认策略为跳过本地已修改块并提示用户确认
-
OpenAPI 同步冲突统一通过文件
contentHash和生成块来源标记识别;应用不提供复杂合并器,最终文件冲突仍交给 Git 处理 -
OpenAPI diff 需识别新增接口、删除接口、方法变化、路径变化、参数变化、请求体变化、响应状态码变化、响应 Schema 变化,并标记潜在破坏性变更
-
OpenAPI 生成的 Mock 规则默认保存到
.http-client/mocks/openapi/{sourceName}.mock.json -
OpenAPI 响应 Schema 校验默认作为用户显式启用的断言能力,不应在普通执行中强制开启
-
Schema 校验失败应生成结构化断言结果,错误码使用
SCHEMA_VALIDATION_ERROR,并展示字段路径、期望类型、实际值摘要 -
OpenAPI 导入、同步、diff、Schema 校验均需生成导入或校验报告,报告可被前端展示,也可作为测试快照保存
创建执行请求模型
-
创建执行请求至少包含:执行类型、文件路径、请求定位信息、环境名、是否流式、是否保存历史
-
请求定位信息
requestSelector至少支持三种模式: -
cursor: 根据光标行列自动识别当前请求 -
requestId: 根据解析后的请求唯一标识执行 -
range: 根据选区或请求块范围执行,供批量执行或选中执行扩展 -
requestId必须在同一文件内容未发生结构性变化时保持稳定,推荐基于文件路径、请求块起始位置、请求名称生成 -
当文件内容变化导致原
requestId失效时,系统应优先尝试通过请求块位置重新定位,并在失败时返回可理解错误 -
当
cursor、requestId、range同时出现时,优先级固定为:requestId>range>cursor
变量解析规则
-
变量解析需区分:全局变量、环境变量、文件内变量、运行时提取变量、链式上下文变量、脚本动态写入变量
-
变量优先级必须固定并在实现中保持一致,默认推荐顺序为:脚本动态写入变量 > 链式上下文变量 > 文件内变量 > 当前环境变量 > 全局变量
-
若同名变量在多个层级同时存在,必须以固定优先级解析,不允许根据加载顺序产生不确定结果
-
未定义变量的处理策略必须显式配置;默认行为为阻断执行并返回
VARIABLE_ERROR -
前置脚本写入的变量应在当前请求执行阶段立即生效;后置脚本写入的变量应在后续请求或链式后续步骤中生效
-
环境切换后应立即重新计算变量解析结果,并同步刷新前端预览
-
变量语法需与 IntelliJ IDEA HTTP Client 保持一致,默认使用
{{variableName}}形式 -
变量解析需支持嵌套引用检测;若出现循环引用,应立即报错并指出引用链
-
变量值默认按字符串处理;若用于 JSON、Header、Query 等上下文,不隐式推断复杂类型,除非脚本显式构造
实时事件模型
-
WebSocket 事件至少支持:
execution.created、execution.started、execution.progress、execution.log、execution.response.meta、execution.response.chunk、execution.assertion、execution.completed、execution.failed、execution.cancelled -
所有事件均需包含
executionId、事件类型、事件时间戳、最小必要载荷 -
前端基于事件流增量渲染执行状态、响应内容、脚本输出与断言结果
-
当事件通道异常断开时,前端需自动尝试重连,并支持按
executionId补拉最终状态或结果快照 -
WebSocket 重连请求需携带客户端已收到的最新
executionId与lastSeq,后端优先从execution_event_index补推缺失事件 -
若缺失事件已被清理或无法补齐,后端需返回
event.replay.unavailable事件,前端改为拉取GET /api/executions/:id/result最终快照 -
WebSocket 事件
seq在同一executionId内必须单调递增,前端需按seq去重和乱序保护
事件背压与高频推送
-
事件通道需区分关键事件与可合并事件;
execution.completed、execution.failed、execution.cancelled、execution.assertion为关键事件,不得被丢弃 -
execution.progress、压测指标、响应 chunk、脚本日志等高频事件允许合并、采样或限频,但最终结果快照必须保留完整状态摘要 -
单个前端连接的 WebSocket 待发送队列需设置上限,默认最多缓存
1000条事件或10MB载荷,超过后优先丢弃可合并事件并发送event.backpressure告警 -
响应 chunk 推送默认按
64KB或100ms任一条件触发批量发送,避免小包过多导致 UI 卡顿 -
压测实时指标默认按
500ms聚合推送一次;用户界面刷新频率不得高于事件聚合频率 -
脚本日志默认按行聚合推送,单次执行最多保留最近
1000条日志,超出后在诊断结果中标记截断 -
当前端重连后,后端优先按
lastSeq补发关键事件和最终快照;对已被采样丢弃的进度事件,只保证最终聚合结果可恢复 -
若 WebSocket 客户端持续消费过慢,后端可关闭该连接并返回可理解关闭原因,前端需自动切换到轮询最终结果快照
执行结果模型
-
最终结果以
ExecutionResult形式固化,用于历史记录、页面刷新恢复、问题排查 -
ExecutionResult至少包含以下部分:summary、request、response、timeline、assertions、diagnostics -
summary包含任务标识、类型、状态、开始时间、结束时间、耗时、环境、文件路径、请求名称 -
request包含原始请求片段、解析后结构、变量替换后的最终请求、执行时环境快照 -
response包含状态码、状态文本、响应头、Cookie、响应体、编码、是否截断、大小 -
timeline包含各阶段耗时信息,如连接建立、TLS、首包、总耗时 -
assertions包含每条断言的名称、结果、失败原因与相关输出 -
diagnostics包含脚本日志、执行告警、错误码、错误消息、行列定位信息 -
ExecutionResult中的小体积快照属于可清理缓存,不作为唯一事实源;缓存被清理后应允许从请求文件、环境文件和响应缓存索引尽量恢复摘要
批量执行模型
-
批量执行使用
type=batch父任务表示,内部包含多个子执行任务 -
父任务负责顺序执行、并行执行、最大并发数、
stopOnFailure等调度策略 -
子任务继续复用普通
Execution结构,不单独发明第二套结果模型 -
父任务取消时必须级联取消所有尚未完成的子任务
链式执行模型
-
链式执行使用
type=chain父任务表示,内部包含按顺序依赖的多个子执行任务 -
父任务维护
chainContext,用于保存变量提取结果并传递给后续步骤 -
每个链式步骤仍然独立产出执行结果,链级结果额外记录变量传递轨迹与中断位置
-
链式执行默认按顺序串行运行,前一步失败时默认中断后续步骤,除非显式配置允许继续
SSE / WebSocket 会话交互
-
SSE 执行需支持手动断开、超时断开、收到完成条件后自动断开三种结束方式
-
WebSocket 会话需支持建立连接、主动发送消息、接收消息、手动断开、异常断开提示
-
WebSocket 会话消息需区分文本、JSON、二进制三类展示方式
-
SSE 与 WebSocket 会话在前端需提供独立会话视图,不与普通 HTTP 响应区完全混用
-
是否将 SSE / WebSocket 会话内容写入历史记录需提供明确策略;默认保存会话摘要与关键消息,不完整持久化无限流数据
执行调度策略
-
系统需定义统一的执行队列与并发上限,避免无限制并发占用本地资源
-
普通 HTTP 执行、批量子任务、链式步骤、SSE、WebSocket 会话均需纳入统一调度体系
-
长连接任务默认计入活动执行数,并支持单独配置最大长连接数
-
当达到并发上限时,新任务应进入
pending队列等待,而不是直接失败 -
是否支持失败重试需提供显式配置;默认单次执行不自动重试
-
默认普通请求最大并发数为
6 -
默认长连接最大并发数为
2 -
默认执行队列最大等待任务数为
100 -
默认批量执行最大并发数为
4
扩展点模型
-
后端内部需预留轻量扩展点注册机制,用于导入器、导出器、执行类型、响应查看器、Schema 校验器和 Mock 生成器扩展
-
扩展点只作为内部模块边界,不设计第三方插件市场,也不要求运行时动态加载外部代码
-
导入器扩展点统一输入源文件路径和工作区上下文,统一输出导入预览、写入计划和不可映射项报告
-
导出器扩展点统一输入解析后请求、环境快照和执行配置,统一输出目标格式文本和差异提示
-
执行类型扩展点统一接入
Execution状态机、事件通道、取消信号、历史固化和调度队列 -
响应查看器扩展点统一基于
contentType、响应大小、编码和流式状态选择展示方式,前端不得在各页面重复判断 -
Schema 校验器扩展点统一输入响应体、content-type、schemaRef 和契约来源,统一输出结构化断言结果
-
Mock 生成器扩展点统一支持从
.http请求、真实响应、OpenAPI operation 三类来源生成规则草案
性能基准
-
解析
1MB.http文件应在300ms内完成后端 AST 生成,解析10MB文件应在3000ms内完成并避免阻塞其他执行任务 -
打开包含
500个请求块的工作区时,请求列表首次可交互时间目标不超过2s -
导入包含
1000个 operation 的 OpenAPI 文件时,预览生成目标时间目标不超过5s -
Mock Server 在
1000条启用规则内的单次匹配目标耗时不超过5ms,命中日志写入不得阻塞响应返回 -
普通响应体
2MB以内可直接内存预览,超过阈值必须分段加载或落盘索引,避免前端一次性渲染大文本 -
WebSocket 事件在普通请求执行中的端到端展示延迟目标不超过
300ms -
压测实时统计在默认阈值内的聚合计算不得成为主要瓶颈,报告中需记录脚本、签名、网络、聚合各阶段耗时占比
-
SQLite 索引重建需按文件数量和耗时输出摘要,用于后续定位大工作区性能问题
压测执行模型
-
压测执行使用
type=load-test表示,目标请求仍通过.http/.rest文件中的请求块选择 -
压测必须由 Go 后端调度执行,前端不得通过循环调用普通执行接口模拟压测
-
压测配置至少包含:并发数、总请求数、持续时间、QPS 限制、预热时间、失败率停止阈值
-
压测执行需支持按总请求数结束、按持续时间结束、用户主动取消、失败率阈值触发停止
-
压测执行默认不保存每次请求的完整响应,仅保存统计摘要、错误摘要和少量采样明细
-
压测执行应复用变量解析、前置脚本、请求构造逻辑;后置脚本与断言默认按采样或聚合策略执行,避免压测过程过重
-
压测执行中的签名计算默认在后端执行;静态签名可在压测开始前预计算,依赖时间戳、nonce、Body 等动态数据的签名需按请求逐次计算
-
压测报告需记录签名计算耗时占比,便于判断压测瓶颈是否来自脚本或签名逻辑
-
压测过程需通过 WebSocket 事件实时推送吞吐、延迟分位数、错误率、状态码分布、已完成请求数
压测保护阈值
-
默认最大压测并发数为
100 -
默认最大压测持续时间为
10min -
默认最大压测请求数为
100000 -
默认最大 QPS 限制为
1000 -
当用户配置超过默认阈值时,界面需提示并要求显式确认
-
压测任务取消后应尽快停止新增请求,并等待已发出的请求完成或超时
压测结果模型
-
压测结果需包含总请求数、成功数、失败数、错误率、总耗时、实际吞吐
-
压测结果需包含延迟统计:
min、avg、p50、p90、p95、p99、max -
压测结果需包含状态码分布、错误类型分布、超时数量
-
压测结果需包含配置快照,便于历史回看时确认当时的并发数、QPS、持续时间和环境
-
压测历史详情页需展示趋势图或分桶数据,产品目标版本至少提供按时间窗口聚合的表格数据
-
压测结果默认只保存聚合统计、分桶指标、错误摘要和少量采样明细,不保存每次请求完整明细
-
压测采样明细需受数量上限控制,默认最多保存
100条错误样本与100条成功样本
Mock Server 支持
-
Mock 支持以本地 Mock Server 形式实现,由 Go 后端提供独立监听端口
-
Mock Server 默认监听
127.0.0.1,端口与主应用服务端口分离 -
默认 Mock Server 端口为
32190,若端口被占用则在32191-32220范围内探测可用端口 -
Mock 规则按工作区隔离管理,默认以工作区内 JSON 文件保存,文件可纳入 Git 版本管理
-
SQLite 不作为 Mock 规则主存储,仅保存 Mock 规则索引、最近加载状态、命中日志和加速查询缓存
-
Mock 规则支持拆分为多个
.mock.json文件,默认加载.http-client/mocks/**/*.mock.json -
多个 Mock 规则文件加载顺序按文件路径字典序稳定排序;实际命中仍以规则
priority、更新时间、规则 ID 作为最终决策 -
不同文件中出现相同 Mock 规则 ID 时视为冲突,应用需在加载预览和 Mock 管理页中提示,默认跳过后加载的重复规则
-
规则级新增、编辑、删除操作最终都必须落到对应
.mock.json文件;SQLite 索引仅在保存成功后更新 -
Mock 规则至少支持按方法、路径、Query、Header、Body 片段匹配请求
-
Mock 路径匹配至少支持精确路径、路径参数、通配符三种模式,例如
/users/1、/users/:id、/files/* -
多条 Mock 规则同时匹配时,按
priority从高到低选择;优先级相同时选择最近更新时间更晚的规则 -
Mock 规则冲突需在保存时给出提示,但允许用户显式保存,用于临时覆盖旧规则
-
Mock 响应至少支持状态码、Header、Body、固定延迟、响应模板
-
Mock 响应 Body 支持 JSON、Text、二进制文件引用
-
Mock 响应模板可读取请求路径参数、Query、Header 和 Body 摘要,用于生成动态响应
-
Mock 响应模板语法优先采用轻量占位符,例如
{{path.id}}、{{query.page}}、{{header.Authorization}}、{{body.userId}} -
Mock 响应模板不得执行任意 JavaScript,避免 Mock 响应生成与脚本运行时耦合;产品目标版本不支持在 Mock 模板中编写复杂控制逻辑
-
Mock 规则支持启用/停用、复制、按标签分组和备注说明,便于同一接口维护多组模拟场景
-
未命中 Mock 规则时默认返回
404;可在工作区设置中配置代理回退到真实上游地址 -
代理回退为工作区级配置,不放在单条 Mock 规则内;启用后所有未命中请求按工作区上游地址转发
-
代理回退模式需在 UI 中明确标识,并在命中日志中区分
mock-hit、mock-miss、proxy-hit、proxy-error -
Mock Server 需记录命中日志,包括时间、方法、路径、匹配规则、响应状态码、耗时
-
Mock 命中日志默认仅记录请求摘要,不保存完整 Header、Body;用户可在设置中调整采样与保留策略
-
Mock 命中日志需支持按数量与时间保留,默认最多保留最近
10000条或7d -
支持从当前
.http请求生成基础 Mock 规则,默认以请求方法和 URL path 作为匹配条件 -
支持从已有响应结果生成 Mock 响应 Body、状态码与 Header,降低手写 Mock 成本
-
支持将工作区 Mock 规则保存为 JSON 文件,并支持从 JSON 文件重新加载;文件适合纳入 Git 版本管理
-
Mock 规则文件保存或重载前需支持预览变更,至少展示新增、更新、冲突、跳过数量
-
Mock 规则文件外部变更时,应用需提示重新加载;文件冲突不做应用内合并,统一交给 Git 处理
-
Mock Server 启停状态需进入本地运行状态恢复;应用重启后默认不自动启动 Mock Server,除非用户显式配置
-
系统托盘菜单需展示 Mock Server 运行状态,并提供打开 Mock 管理页、启动、停止快捷操作
错误模型
-
错误码至少包含:
PARSE_ERROR、VARIABLE_ERROR、SCRIPT_ERROR、REQUEST_ERROR、ASSERTION_ERROR、TIMEOUT_ERROR、CANCELLED、FILE_CONFLICT、SCHEMA_VERSION_UNSUPPORTED、SCHEMA_VALIDATION_ERROR、OPENAPI_PARSE_ERROR、OPENAPI_SYNC_CONFLICT、INDEX_REBUILD_ERROR、MIGRATION_ERROR、INTERNAL_ERROR -
语法错误、变量错误、脚本错误应尽量返回可映射到编辑器的行列定位信息
脚本与断言模型
脚本运行时边界
-
请求前置脚本、请求后置脚本、断言统一采用 JavaScript 作为脚本语言
-
后端采用嵌入式 JavaScript 运行时执行脚本,与 Go 执行器运行在同一进程内
-
脚本运行时需提供稳定、可控、可测试的内置 API,不依赖浏览器环境
-
脚本运行时默认不提供任意文件系统访问、任意网络访问、动态模块安装等能力;本条仅定义运行时能力边界
-
脚本运行时默认不提供浏览器 DOM、
window、document等浏览器对象
脚本生命周期
-
请求执行顺序为:解析请求 -> 变量替换 -> 前置脚本 -> 发送请求 -> 后置脚本 -> 断言 -> 结果固化
-
批量执行与链式执行中的每个子任务均独立执行上述生命周期
-
前置脚本可修改最终请求上下文,后置脚本可读取响应并提取变量
签名计算支持
-
签名计算默认通过后端前置脚本实现,执行时机为变量替换之后、请求发送之前
-
前置脚本可读取当前请求、环境变量、文件内变量和脚本动态变量,用于构造签名原文
-
前置脚本可将签名结果写回 Header、Query、Body 或运行时变量
-
签名计算不得在前端 UI 线程中执行;普通执行、批量执行、链式执行、压测执行均由后端统一完成签名
-
内置
cryptoAPI 的底层实现应优先使用 Go 原生实现,JavaScript 脚本只负责编排签名原文和写回请求 -
签名计算失败应中断当前请求,并返回
SCRIPT_ERROR -
签名计算相关日志需进入脚本日志,但默认仅记录计算阶段与错误摘要,不主动输出 secret、token 等原始变量值
-
压测、批量执行、链式执行中的每个子请求均需独立执行签名前置脚本,确保时间戳、nonce、签名值按请求生成
脚本上下文
-
脚本上下文至少提供:当前环境变量、文件内变量、全局变量、当前请求对象、当前响应对象、链式上下文对象
-
前置脚本可访问请求对象但不可访问响应对象
-
后置脚本与断言可同时访问请求对象和响应对象
-
脚本对变量的写入应支持回填到执行上下文,以便后续链式步骤使用
脚本内置 API
-
至少提供读取变量、设置变量、读取请求、修改请求、读取响应、输出日志、添加断言结果等内置 API
-
至少提供便于 JSON、Header、状态码校验的断言辅助 API
-
脚本输出日志需进入实时事件流与最终诊断结果
-
内置 API 需提供稳定命名,至少包括:
vars.get(name)、vars.set(name, value)、request.get()、request.setHeader(name, value)、request.setQuery(name, value)、request.setBody(value)、response.get()、log.info(message)、assert.equal(actual, expected, message) -
后置脚本与断言需支持异步 API,但必须在脚本超时范围内完成
-
若支持
console.log,其输出需等价映射到log.info -
脚本
assert失败必须生成结构化断言结果,而不是仅输出文本日志 -
内置
cryptoAPI 至少提供:crypto.hmacSha256Hex(secret, data)、crypto.sha256Hex(data)、crypto.md5Hex(data)、crypto.base64Encode(data)、crypto.uuid()
脚本执行约束
-
每段脚本需设置独立超时时间,避免单个脚本阻塞整个执行任务
-
脚本执行失败应中断当前任务,并以
SCRIPT_ERROR返回 -
断言失败应固化为
ASSERTION_ERROR,并在结果中展示断言明细 -
默认前置脚本超时时间为
3000ms -
默认后置脚本超时时间为
3000ms -
默认单次 HTTP 请求超时时间为
30000ms
数据存储模型
存储边界
-
原始
.http/.rest文件不写入 SQLite,仅以本地文件形式保存 -
SQLite 仅用于索引、缓存、命中日志,不保存环境变量、项目配置、Mock 规则等事实源数据
-
Mock 规则源数据默认保存为工作区 JSON 文件,不以 SQLite 作为唯一事实来源
-
环境变量与项目配置默认保存为工作区 JSON 文件,不以 SQLite 作为唯一事实来源
-
OpenAPI 原始契约文件与
.http-client/openapi/sources.json默认保存为工作区文件,不以 SQLite 作为唯一事实来源 -
OpenAPI 派生的
.http请求模板、Mock 规则文件、Schema 校验映射均按工作区文件管理,SQLite 仅保存可重建索引与摘要
SQLite 设计
-
至少包含以下数据表:
execution_history_index、execution_event_index、response_cache_index、recent_file_cache、mock_rule_index、mock_hit_logs、openapi_source_index、openapi_operation_index -
execution_history_index保存执行摘要、文件路径、请求标识、环境、状态、耗时、时间范围、结果索引信息 -
execution_event_index保存可选事件索引信息,用于快速回放关键执行过程 -
response_cache_index保存响应体、事件载荷、历史快照等落盘缓存文件的索引与摘要 -
recent_file_cache保存最近打开文件与最近访问目录,可清理、可重建 -
mock_rule_index保存 Mock 规则文件索引与摘要,便于快速查询和启动 Mock Server -
openapi_source_index保存 OpenAPI 源文件索引与摘要,便于快速展示契约来源和同步状态 -
openapi_operation_index保存 OpenAPI operation 索引与生成产物摘要,便于接口搜索、diff 和同步预览
索引重建策略
-
SQLite 索引与缓存允许删除后重建,不得作为工作区事实源数据的唯一存储
-
索引重建需扫描
.http-client/environments.json、.http-client/settings.json、.http-client/mocks/**/*.mock.json、.http-client/openapi/sources.json、OpenAPI 源文件、响应缓存目录、事件缓存目录和最近文件缓存来源 -
索引重建完成后需返回重建摘要,至少包含扫描文件数、重建索引数、跳过数、错误数和错误摘要
-
若 SQLite 损坏,应用应提供“重建索引”恢复路径;命中日志可备份后清空,不阻断工作区继续使用
-
索引重建过程中不得修改工作区事实源 JSON 文件
数据保留策略
-
请求历史需支持数量上限与清理策略,避免数据库无限增长
-
响应体过大时允许落盘为单独文件,仅在 SQLite 中保存索引与摘要信息
-
批量执行与链式执行需支持父子任务关系索引,便于查询与展示
-
SSE 与 WebSocket 长连接历史需支持消息数量截断与摘要化存储,避免无限增长
-
默认历史记录保留上限为
1000条 -
超出保留上限时,系统按最旧优先策略自动清理
大响应体与二进制处理
-
系统需定义响应体内存预览阈值、自动落盘阈值、历史存储阈值,并在前后端保持一致
-
二进制响应默认不直接全文渲染,优先展示摘要信息、大小、MIME 类型与保存入口
-
大文本响应需支持分段加载、截断提示、另存为文件
-
历史回看时若响应体已落盘,系统需支持按索引重新加载该响应内容
-
默认响应体内存预览阈值为
2MB -
默认自动落盘阈值为
5MB -
默认历史存储阈值为
10MB
数据目录约束
-
应用需提供独立的数据目录用于 SQLite、日志、缓存响应体、运行时文件存储
-
工作区
.http-client/目录仅用于保存可版本管理的事实源文件,例如环境变量、项目配置、Mock 规则与 Mock 静态资源 -
工作区
.http-client/openapi/目录仅用于保存 OpenAPI 源映射、同步配置和可版本管理的派生关系,不用于保存运行时响应缓存 -
SQLite、响应缓存、事件缓存、日志、诊断包、备份文件默认保存到应用数据目录,不写入工作区
.http-client/ -
Mock 静态资源属于 Mock 规则事实源,可保存在工作区
.http-client/mocks/assets/并随规则文件进入 Git;运行时响应缓存不得放入该目录 -
系统托盘菜单中的“打开数据目录”需直接定位到该目录
环境配置边界
-
环境配置默认按工作区维度隔离存储,不同工作区之间互不干扰
-
全局环境变量仅作为跨工作区共享的可选能力,不应覆盖工作区级环境的默认行为
-
需提供默认环境选择规则:若请求或工作区未显式指定环境,则使用最近一次选中的工作区默认环境
-
需明确请求执行时所使用的环境快照,确保历史回看时可以看到当时的实际变量值
-
环境变量需支持导入导出,导出格式需可读、可版本管理
默认值与配置优先级
-
应用默认值需集中定义,后端默认值源建议位于
backend/internal/model/defaults.go,前端展示默认值需由 API 或生成类型获得,避免前后端各自硬编码 -
配置优先级需固定为:本次执行请求显式参数 > 当前工作区设置 > 应用内置默认值
-
环境变量解析优先级继续遵循变量解析规则,不与应用配置优先级混用
-
执行类默认值至少包含:普通请求超时、前置脚本超时、后置脚本超时、普通请求最大并发数、长连接最大并发数、批量执行最大并发数、执行队列最大等待任务数
-
压测类默认值至少包含:最大并发数、最大持续时间、最大请求数、最大 QPS、采样明细数量、实时指标推送间隔
-
Mock 类默认值至少包含:默认端口、端口探测范围、未命中响应策略、命中日志保留数量、命中日志保留天数、代理回退默认状态
-
OpenAPI 类默认值至少包含:生成请求目录、生成 Mock 目录、同步策略、是否默认启用 Schema 校验、默认
baseUrl变量名 -
UI 类默认值至少包含:最近文件数量、历史分页大小、日志展示行数、响应体内存预览阈值、响应体自动落盘阈值
-
设置页展示的默认值需说明来源:内置默认值、工作区覆盖值或本次执行覆盖值
-
用户恢复默认值时,只应删除工作区覆盖项,不应改写内置默认值或历史执行快照
状态恢复策略
-
页面刷新后应恢复最近打开文件、当前选中文件、最近一次执行结果和当前环境选择
-
浏览器重新打开后应恢复最近工作区与最近会话摘要,但不强制恢复未保存临时编辑内容
-
对于正在运行中的普通执行任务,前端重新连接后应根据
executionId自动恢复状态展示 -
对于 SSE / WebSocket 长连接,会话断开后默认不自动恢复原始连接,但需保留断开前的摘要与日志
-
页面刷新后应恢复编辑器光标位置、滚动位置与当前激活的响应标签页
-
未保存草稿默认仅保存在浏览器当前会话内,浏览器完全关闭后不保证恢复
前端信息架构
主界面布局
-
主界面采用三栏布局:左侧资源区、中间编辑区、右侧或下方响应区
-
左侧资源区至少包含文件树、最近文件、请求历史入口
-
中间编辑区使用 Monaco Editor,负责
.http/.rest编辑、语法高亮、当前请求高亮和错误定位 -
响应区至少包含
Body、Headers、Cookies、Timeline、Logs标签页 -
响应区需支持普通 HTTP 响应视图与 SSE / WebSocket 会话视图切换
历史详情页
-
历史详情页需展示执行摘要、请求快照、响应快照、断言结果、脚本日志、时间线
-
历史详情页需提供重新执行、复制 curl、打开源文件、定位请求块入口
-
压测历史详情页需展示吞吐、延迟分位数、错误率、状态码分布和配置快照
环境管理页
-
环境管理页需按工作区展示环境列表
-
环境变量表至少包含变量名、变量值、作用域、更新时间
-
环境管理页需提供新增、编辑、删除、导入、导出、设为默认环境操作
设置页
-
设置页需包含本地服务配置、执行默认值、历史保留策略、日志与诊断入口、数据目录入口
-
设置页修改默认值后需立即影响新创建的执行任务,不影响已运行任务
Mock 管理页
-
Mock 管理页需展示当前工作区 Mock Server 状态、访问地址、启动/停止操作
-
Mock 管理页需展示 Mock 规则列表,至少包含方法、路径、状态码、延迟、启用状态、最近命中时间
-
Mock 规则列表需支持按启用状态、方法、路径、标签、命中状态筛选,并支持按优先级拖拽排序
-
Mock 规则编辑器需支持匹配条件、优先级、标签、备注、响应状态码、响应 Header、响应 Body、延迟、模板变量
-
Mock 规则编辑器需在保存前展示冲突提示,说明可能被覆盖或覆盖其他规则的匹配范围
-
Mock 响应 Body 编辑器需支持 JSON Pretty、Raw Text、二进制文件引用三种模式
-
Mock 管理页需提供从最近一次真实响应生成 Mock 规则的入口
-
Mock 管理页需展示命中日志,并支持按方法、路径、状态码、命中/未命中过滤
-
Mock 命中日志详情需展示匹配结果、规则名称、请求摘要、响应来源、代理回退状态与耗时
-
请求编辑器需提供“从当前请求生成 Mock 规则”的入口
-
Mock 管理页需提供 Mock 规则文件保存、重载、预览变更、清空命中日志操作
OpenAPI 管理页
-
OpenAPI 管理页需展示当前工作区已登记的 OpenAPI 契约源,至少包含名称、源文件路径、版本、接口数量、最近同步时间、同步状态
-
OpenAPI 管理页需提供导入本地 OpenAPI 文件、重新解析、同步预览、应用同步、移除源映射操作
-
OpenAPI 导入向导需展示生成目标,包括
.http请求文件、Mock 规则文件、Schema 校验映射,并允许用户逐项勾选 -
OpenAPI 导入预览需展示将要新增、更新、跳过、冲突的请求块和 Mock 规则,默认不直接写入文件
-
OpenAPI 同步预览需突出本地已修改请求块,默认跳过并提示用户手动确认是否覆盖
-
OpenAPI diff 视图需按接口维度展示新增、删除、变更和潜在破坏性变更,支持按 tag、路径、方法过滤
-
请求编辑器需展示 OpenAPI 来源标记,并提供打开来源 operation、重新生成当前请求模板、启用响应 Schema 校验入口
-
响应区需提供“按 OpenAPI Schema 校验当前响应”入口,校验结果进入断言结果视图
-
Mock 管理页需提供“从 OpenAPI 生成 Mock 骨架”的入口,并展示生成来源、operationId 和响应状态码
UI 空状态与异常状态
-
首次启动且未打开工作区时,主界面需展示打开工作区、打开
.http文件、新建示例文件三个入口 -
当前工作区无
.http/.rest文件时,文件树需展示空状态,并提供新建请求文件和导入 OpenAPI 的入口 -
请求文件解析失败时,编辑器需保留原文本展示,并在问题面板中列出可定位的解析错误
-
未选择请求块时,响应区需展示引导状态,提示用户将光标放到请求块内或从请求列表选择请求
-
执行中状态需清晰展示当前阶段,例如解析、变量替换、前置脚本、发送请求、接收响应、断言、固化历史
-
请求取消、超时、网络失败、脚本失败、断言失败、Schema 校验失败需使用不同错误状态展示,不得统一显示为“请求失败”
-
WebSocket 断开时,页面需展示连接状态和恢复动作;重连成功后需提示是否已补齐事件或已切换到结果快照
-
外部文件变更提示需区分“可安全重载”和“当前存在未保存修改”,避免用户误覆盖编辑内容
-
大响应体被截断、二进制响应不可直接预览、日志被截断时,界面需给出明确原因和可用操作
-
OpenAPI 导入和同步预览为空时,需说明没有可写入变更,而不是展示空白列表
快捷键与交互一致性
-
核心快捷键需集中定义,避免不同页面重复绑定造成冲突
-
MVP 至少支持执行当前请求、保存当前文件、打开文件、搜索请求、取消当前执行五类快捷操作
-
快捷键触发的执行行为必须与按钮点击行为复用同一前端 action,不得分叉实现
-
弹窗、抽屉、预览面板需统一支持
Escape关闭和焦点回到触发元素 -
危险或不可逆操作需提供确认,例如清空命中日志、删除 Mock 规则、覆盖本地已修改的 OpenAPI 生成块
-
前端所有异步操作需具备加载中、成功、失败、重试或关闭入口,不允许只在控制台输出错误
可访问性与国际化
-
前端交互控件需具备键盘可达性,核心操作至少支持 Tab 导航与 Enter / Escape 确认取消
-
编辑器外的按钮、菜单、标签页、弹窗需具备可理解的 aria label 或等效可访问名称
-
默认界面语言为中文,文案需集中管理,避免散落在组件内部
-
产品目标版本需预留国际化结构,允许后续增加英文界面
-
时间、文件大小、耗时等显示格式需统一封装,避免各组件自行格式化
MVP 范围
MVP 必须完成
-
本地服务启动、浏览器访问、系统托盘打开页面与退出服务
-
本地工作区文件打开、保存、另存为、最近文件、外部变更提示
-
.http文件多请求解析、当前请求定位、变量替换、基础错误定位 -
单请求执行、执行取消、响应展示、历史记录回看
-
基础环境管理与环境切换
-
统一
Execution模型、REST 控制面、WebSocket 事件通道 -
JavaScript 前置脚本、后置脚本、基础断言能力
产品目标版本必须完成
-
批量执行
-
链式执行
-
SSE 支持
-
WebSocket 会话支持
-
对目标接口发起轻量压测
-
本地 Mock Server 与 Mock 规则管理
-
curl 导出、Postman collection 导入与 OpenAPI 导入同步
-
完整兼容性回归测试集
可后续迭代
-
测试报告导出增强
-
更丰富的请求可视化预览
-
更完整的执行时间线分析
验收标准
MVP 功能验收
-
用户可直接打开真实
.http文件并执行当前请求,无需改写为应用私有格式 -
用户可在同一文件中执行多个请求块,并正确区分当前请求与其他请求
-
用户可切换环境后立即看到变量替换结果变化,并执行对应请求
-
用户可在长时间请求执行过程中看到实时状态变化,并主动取消任务
-
用户可在历史记录中重新查看执行结果,并恢复请求上下文
产品目标版本功能验收
-
用户可对当前请求发起轻量压测,并实时查看吞吐、延迟分位数和错误率
-
用户可启动本地 Mock Server,并通过 Mock 地址访问已配置的模拟响应
-
用户可为同一路径维护多条 Mock 规则,并通过优先级控制实际命中的响应
-
用户可从真实响应生成 Mock 规则,并保存到工作区 Mock 规则文件交给 Git 管理
-
用户可导入 OpenAPI 文件生成
.http请求模板,并在不覆盖本地修改的前提下预览和应用后续同步 -
用户可基于 OpenAPI 响应 Schema 校验真实响应,并在断言结果中看到字段级错误
兼容性验收
-
建立一套分层的真实
.http示例文件集,至少区分MVP用例集与产品目标版本完整用例集 -
每次阶段发布前均需执行对应阶段范围内的兼容性回归测试;产品目标版本发布前需执行完整兼容性回归测试
-
若发现与 IntelliJ IDEA HTTP Client 行为不一致,需记录差异并在发布前修复或明确列入已知限制
质量验收
-
后端需具备解析器、执行器、脚本运行时、API 层单元测试
-
前端需具备核心组件测试与关键交互测试
-
集成测试需覆盖文件打开、请求执行、事件推送、历史回看、环境切换等主流程
-
压测测试需覆盖并发限制、QPS 限制、取消、失败率停止阈值和结果统计准确性
-
Mock 测试需覆盖规则匹配、优先级冲突、未命中、代理回退、动态响应、延迟、命中日志和启停状态
非功能验收
-
冷启动到本地服务可访问的目标时间不超过
3s -
打开
1MB.http文件并完成请求块识别的目标时间不超过1s -
普通 JSON 响应
2MB以内 Pretty 展示目标时间不超过1s -
空闲状态后端常驻内存目标不超过
150MB -
前端主要交互不应因流式响应持续追加而出现明显卡顿
-
大响应体、长连接和批量执行场景不得导致 UI 主线程长时间阻塞
-
压测执行期间前端统计展示刷新频率需受控,避免高频事件导致 UI 卡顿
质量门禁与完成定义
-
每个 MVP 任务完成前必须能对应到需求编号、实现提交、测试用例和验收项
-
后端代码合入前至少通过:
go test ./backend/...、API envelope 测试、parser golden tests、核心执行集成测试 -
前端代码合入前至少通过:
npm run test --prefix frontend、关键组件测试、主流程 E2E 或对应替代验证 -
契约相关变更合入前必须通过内部 API OpenAPI 契约校验、前端类型生成校验和 API 示例 JSON 快照校验
-
工作区 JSON schema 变更合入前必须通过 schema 校验、低版本迁移测试和高版本拒绝写入测试
-
Mock、OpenAPI、环境变量、设置文件的写入逻辑变更必须覆盖
contentHash冲突检测和原子写入失败路径 -
事件流、压测、SSE、WebSocket 相关变更必须覆盖慢客户端、断线重连、取消和最终结果快照恢复
-
大响应体、二进制响应、日志截断相关变更必须覆盖阈值、落盘、截断提示和历史回看
-
任一阶段发布前需更新兼容矩阵、测试 fixture、API 示例和实施状态,避免文档与实现漂移
-
若某项验收无法自动化,需在测试记录中说明手工验证步骤、输入数据和观察结果
-
完成定义固定为:功能可用、错误可理解、状态可恢复、数据不丢失、测试有覆盖、文档已同步
诊断与运维约束
日志与诊断
-
系统需区分应用日志、执行日志、脚本日志、会话日志,避免所有日志混入同一输出
-
日志需至少支持
error、warn、info、debug四级别 -
每次执行任务需具备可追踪的日志标识,便于通过
executionId检索相关日志 -
设置页或托盘菜单需提供“打开日志目录”或等效入口,便于排查问题
-
用户需能够导出基础诊断信息,至少包含版本号、系统信息、最近错误摘要、最近执行日志索引
-
日志文件命名格式为
{category}-{yyyyMMdd}.log -
执行日志需包含
executionId,便于与历史记录互相定位 -
诊断包导出格式为 zip,目录结构至少包含
summary.json、logs/、recent-errors.json、runtime.json
故障恢复
-
本地服务异常退出后,再次启动时应提示最近一次非正常退出,并提供查看日志入口
-
若 SQLite 或缓存文件损坏,系统需给出可理解的错误提示,并提供“重建索引”恢复入口
-
重建索引失败不应阻断工作区事实源文件访问;用户仍可打开、编辑、保存
.http与.http-client/*.json文件
构建与发布命令
本地开发命令
-
后端开发命令:
go run ./backend -
前端开发命令:
npm run dev --prefix frontend -
前端构建命令:
npm run build --prefix frontend -
后端测试命令:
go test ./backend/... -
前端测试命令:
npm run test --prefix frontend
打包命令
-
统一构建命令:
npm run build --prefix frontend后执行go build ./backend -
前端构建产物目录固定为
frontend/dist -
后端需将
frontend/dist作为静态资源托管目录 -
产品目标版本默认将前端静态资源嵌入 Go 二进制,MVP 阶段允许以目录形式随包分发
测试计划
后端测试
-
Parser 使用 golden tests 覆盖
.http/.rest解析、错误定位、变量引用、请求块定位 -
Executor 使用 integration tests 覆盖普通 HTTP、取消、超时、重定向、Cookie、TLS 配置
-
Execution 使用状态机测试覆盖状态流转、父子任务、取消级联、队列调度
-
Script runtime 使用单元测试覆盖变量读写、请求修改、响应读取、断言失败、超时
-
API 层使用 handler tests 覆盖统一响应 envelope、错误模型、分页与状态查询
-
OpenAPI 模块测试覆盖 3.0 / 3.1 解析、请求模板生成、Mock 骨架生成、同步预览、diff、响应 Schema 校验
前端测试
-
Editor 组件测试覆盖当前请求定位、错误标记、变量预览
-
Response 组件测试覆盖标签页切换、Raw / Pretty / Preview、流式 chunk 增量渲染
-
History 测试覆盖历史列表分页、详情回看、重新执行
-
Environment 测试覆盖环境切换、变量编辑、导入导出
-
Mock 管理测试覆盖规则新增、编辑、启停、优先级排序、文件保存、文件重载、命中日志过滤
-
OpenAPI 管理测试覆盖导入向导、同步预览、diff 过滤、生成目标勾选、Schema 校验结果展示
端到端测试
-
E2E 测试覆盖打开工作区、打开
.http文件、执行当前请求、查看响应、取消请求、历史回看 -
兼容性回归测试需按附录 A 的用例路径组织
-
压测 E2E 测试需覆盖创建压测、实时统计更新、主动取消、历史报告回看
-
Mock E2E 测试需覆盖从请求生成 Mock 规则、从真实响应生成 Mock 规则、启动 Mock Server、访问 Mock 响应、查看命中日志、保存与重载规则文件
-
OpenAPI E2E 测试需覆盖导入契约、生成
.http请求、生成 Mock 骨架、执行请求、校验响应 Schema、预览同步冲突
支持矩阵与发布约束
平台支持矩阵
-
当前最低支持版本定义为:Windows 10、macOS 12、主流 Linux x86_64 发行版
-
推荐浏览器定义为:Chrome / Edge 最新两个稳定版本
-
对于不同平台上的托盘、文件路径、默认浏览器唤起行为差异,需建立平台差异清单
打包与升级约束
-
打包产物需明确区分安装目录、应用数据目录、缓存目录、日志目录
-
版本升级时需提供 SQLite 缓存数据库迁移、工作区 JSON schema 迁移与失败回滚策略
-
升级后不得破坏现有工作区配置、环境配置、历史记录索引
-
安装包与二进制发布说明需明确首次启动行为、数据目录位置、卸载后数据保留策略
导入导出映射
-
curl 导出需覆盖方法、URL、Query、Header、Cookie、Body、代理和 TLS 相关配置
-
curl 导出遇到无法表达的应用内部配置时,需在导出结果旁展示差异提示
-
Postman collection 导入需覆盖 collection、folder、request、environment variables 的基础映射
-
Postman 导入遇到不可映射字段时,不应静默丢弃,需生成导入报告
-
导入报告至少包含:成功数量、失败数量、跳过数量、不可映射字段列表、源文件路径
-
导入后的请求默认生成
.http文件,原始 Postman collection 不写入数据库 -
OpenAPI 导入需覆盖
paths、tags、operationId、parameters、requestBody、responses、servers的基础映射 -
OpenAPI 导入遇到不可映射字段时,不应静默丢弃,需生成导入报告,并在报告中标记字段路径与影响范围
-
OpenAPI 导入后的请求默认生成
.http文件,原始 OpenAPI 文件仍保留为工作区契约源,不写入数据库 -
OpenAPI 同步需保留本地手写脚本、断言和备注,除非用户显式选择重新生成对应请求块
-
OpenAPI diff 报告需区分兼容变更与潜在破坏性变更,供同步预览和发布检查复用
附录 A:兼容矩阵草案
| 语法项 | 产品目标版本 | MVP | 差异说明 | 回归用例 |
|---|---|---|---|---|
.http 文件 |
支持 | 支持 | 无 | compat/basic/get.http |
.rest 文件 |
支持 | 支持 | 与 .http 同解析流程 |
compat/basic/rest-file.rest |
### 请求分隔 |
支持 | 支持 | 无 | compat/parser/multiple-requests.http |
| 请求命名 | 支持 | 支持 | 需展示在执行摘要与历史记录中 | compat/parser/named-request.http |
| 行注释与块注释 | 支持 | 支持 | 与 IntelliJ IDEA HTTP Client 保持一致 | compat/parser/comments.http |
| 自定义 HTTP 方法 | 支持 | 支持 | 不限制为内置方法枚举 | compat/request/custom-method.http |
| Header 解析 | 支持 | 支持 | 支持同名 Header 多值 | compat/request/headers.http |
| Query 参数 | 支持 | 支持 | URL 原样解析,变量替换后执行 | compat/request/query-vars.http |
| JSON Body | 支持 | 支持 | 支持格式化预览 | compat/body/json.http |
| XML Body | 支持 | 支持 | 支持 Raw 与 Pretty 预览 | compat/body/xml.http |
| Text Body | 支持 | 支持 | 按文本展示 | compat/body/text.http |
| Form URL Encoded | 支持 | 产品目标版本 | MVP 可先作为 Raw Body 执行 | compat/body/form-url-encoded.http |
| Multipart Form Data | 支持 | 产品目标版本 | 需覆盖文本字段与文件字段 | compat/body/multipart.http |
| 二进制 Body | 支持 | 产品目标版本 | 需结合文件引用处理 | compat/body/binary-file.http |
| 外部文件引用 | 支持 | 产品目标版本 | 路径解析遵循工作区模型 | compat/body/external-file.http |
| 文件内变量 | 支持 | 支持 | 参与固定优先级解析 | compat/vars/file-vars.http |
| 环境变量 | 支持 | 支持 | 工作区级隔离 | compat/vars/environment-vars.http |
| 全局变量 | 支持 | 产品目标版本 | 作为跨工作区可选能力 | compat/vars/global-vars.http |
| 变量嵌套引用 | 支持 | 支持 | 循环引用需报错 | compat/vars/nested-vars.http |
| Cookie 管理 | 支持 | 产品目标版本 | 需展示 Cookie 视图 | compat/request/cookies.http |
| 重定向 | 支持 | 产品目标版本 | 需展示最终 URL 与跳转链 | compat/request/redirect.http |
| 代理配置 | 支持 | 产品目标版本 | 需在请求配置中体现 | compat/request/proxy.http |
| SSL/TLS 配置 | 支持 | 产品目标版本 | 包含跳过校验与证书配置 | compat/request/tls.http |
| 客户端证书 | 支持 | 产品目标版本 | 证书文件按工作区路径规则解析 | compat/request/client-cert.http |
| 前置脚本 | 支持 | 支持 | JavaScript 运行时执行 | compat/scripts/pre-request.http |
| 后置脚本 | 支持 | 支持 | 支持变量回填 | compat/scripts/post-request.http |
| 断言 | 支持 | 支持 | 失败生成结构化断言结果 | compat/scripts/assertions.http |
| 链式请求 | 支持 | 产品目标版本 | 通过 chainContext 传递变量 |
compat/flow/chain.http |
| 批量执行 | 支持 | 产品目标版本 | 父子 Execution 模型 |
compat/flow/batch.http |
| SSE | 支持 | 产品目标版本 | 独立会话视图 | compat/stream/sse.http |
| WebSocket | 支持 | 产品目标版本 | 支持收发消息与会话摘要 | compat/stream/websocket.http |
| 轻量压测 | 支持 | 产品目标版本 | 基于 load-test Execution 类型 |
compat/load-test/basic-load-test.http |
| 本地 Mock Server | 支持 | 产品目标版本 | 工作区级 Mock 规则与命中日志 | compat/mock/basic-mock.json |
| 导出 curl | 支持 | 产品目标版本 | 保持请求语义一致 | compat/import-export/export-curl.http |
| 导入 Postman | 支持 | 产品目标版本 | 不可映射项需提示 | compat/import-export/postman-collection.json |
| 导入 OpenAPI | 支持 | 产品目标版本 | 作为接口契约来源生成 .http、Mock 骨架和 Schema 校验映射 |
compat/import-export/openapi-import.yaml |
| OpenAPI 同步 | 支持 | 产品目标版本 | 预览 diff 并保护本地已修改请求块 | compat/import-export/openapi-sync.yaml |
| OpenAPI Schema 校验 | 支持 | 产品目标版本 | 用户显式启用后生成结构化断言结果 | compat/import-export/openapi-schema-validation.http |
附录 B:API 示例 JSON
统一成功响应
{
"success": true,
"data": {
"executionId": "exec_01HZY7R4S7M4H4QF3W2K2N4H8A",
"status": "pending",
"type": "http"
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y3",
"timestamp": "2026-06-06T10:20:30Z"
}
统一失败响应
{
"success": false,
"data": null,
"error": {
"code": "VARIABLE_ERROR",
"message": "Undefined variable: token",
"details": {
"variableName": "token"
},
"location": {
"filePath": "C:/workspace/api/demo.http",
"line": 8,
"column": 23
}
},
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y3",
"timestamp": "2026-06-06T10:20:31Z"
}
创建执行请求
{
"operationId": "op_exec_01HZY7R4S6",
"type": "http",
"filePath": "C:/workspace/api/demo.http",
"requestSelector": {
"mode": "cursor",
"line": 18,
"column": 5
},
"environment": "dev",
"stream": true,
"persistHistory": true
}
创建压测请求
{
"operationId": "op_loadtest_01HZY7R4S6",
"type": "load-test",
"filePath": "C:/workspace/api/demo.http",
"requestSelector": {
"mode": "requestId",
"requestId": "req_list_users"
},
"environment": "dev",
"stream": true,
"persistHistory": true,
"loadTest": {
"concurrency": 20,
"totalRequests": 1000,
"durationSeconds": 60,
"qpsLimit": 100,
"warmupSeconds": 5,
"stopOnErrorRate": 0.2
}
}
查询执行状态响应
{
"success": true,
"data": {
"executionId": "exec_01HZY7R4S7M4H4QF3W2K2N4H8A",
"type": "http",
"status": "running",
"stage": "sending",
"startedAt": "2026-06-06T10:20:30Z",
"finishedAt": null,
"error": null
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y4",
"timestamp": "2026-06-06T10:20:30Z"
}
WebSocket 事件 envelope
{
"type": "execution.response.chunk",
"executionId": "exec_01HZY7R4S7M4H4QF3W2K2N4H8A",
"seq": 12,
"timestamp": "2026-06-06T10:20:31Z",
"payload": {
"contentType": "application/json",
"encoding": "utf-8",
"chunk": "{\"id\":1,\"name\":\"demo\"}",
"offset": 0,
"done": false
}
}
压测进度事件
{
"type": "execution.loadtest.progress",
"executionId": "exec_01HZY7R4S7M4H4QF3W2K2N4H8B",
"seq": 42,
"timestamp": "2026-06-06T10:20:40Z",
"payload": {
"completedRequests": 500,
"successRequests": 490,
"failedRequests": 10,
"errorRate": 0.02,
"throughput": 83.3,
"latency": {
"avgMs": 45,
"p95Ms": 120,
"p99Ms": 240
},
"statusCodes": {
"200": 490,
"500": 10
}
}
}
ExecutionResult 示例
{
"summary": {
"executionId": "exec_01HZY7R4S7M4H4QF3W2K2N4H8A",
"type": "http",
"status": "completed",
"startedAt": "2026-06-06T10:20:30Z",
"finishedAt": "2026-06-06T10:20:31Z",
"durationMs": 864,
"environment": "dev",
"filePath": "C:/workspace/api/demo.http",
"requestName": "List users"
},
"request": {
"raw": "GET https://api.example.com/users\nAccept: application/json",
"resolved": {
"method": "GET",
"url": "https://api.example.com/users",
"headers": {
"Accept": "application/json"
},
"body": null
},
"environmentSnapshot": {
"name": "dev",
"variables": {
"baseUrl": "https://api.example.com"
}
}
},
"response": {
"statusCode": 200,
"statusText": "OK",
"headers": {
"Content-Type": "application/json"
},
"cookies": [],
"body": "[{\"id\":1,\"name\":\"demo\"}]",
"bodyEncoding": "utf-8",
"bodyTruncated": false,
"size": 24
},
"timeline": {
"dnsMs": null,
"connectMs": 18,
"tlsMs": 42,
"firstByteMs": 210,
"totalMs": 864
},
"assertions": [],
"diagnostics": {
"logs": [],
"warnings": [],
"error": null
}
}
压测结果示例
{
"summary": {
"executionId": "exec_01HZY7R4S7M4H4QF3W2K2N4H8B",
"type": "load-test",
"status": "completed",
"requestName": "List users",
"durationMs": 60000,
"environment": "dev"
},
"loadTest": {
"config": {
"concurrency": 20,
"totalRequests": 1000,
"durationSeconds": 60,
"qpsLimit": 100,
"warmupSeconds": 5,
"stopOnErrorRate": 0.2
},
"summary": {
"totalRequests": 1000,
"successRequests": 980,
"failedRequests": 20,
"errorRate": 0.02,
"throughput": 16.3
},
"latency": {
"minMs": 12,
"avgMs": 45,
"p50Ms": 38,
"p90Ms": 80,
"p95Ms": 120,
"p99Ms": 240,
"maxMs": 500
},
"statusCodes": {
"200": 980,
"500": 20
},
"errors": {
"REQUEST_ERROR": 20
}
}
}
文件读取响应
{
"success": true,
"data": {
"filePath": "C:/workspace/api/demo.http",
"workspacePath": "C:/workspace/api",
"content": "GET https://api.example.com/users\nAccept: application/json",
"lastModifiedAt": "2026-06-06T10:00:00Z",
"version": "filever_01HZY7R4S7"
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y4",
"timestamp": "2026-06-06T10:20:30Z"
}
文件保存请求
{
"operationId": "op_save_file_01HZY7R4S7",
"filePath": "C:/workspace/api/demo.http",
"content": "GET https://api.example.com/users\nAccept: application/json",
"baseVersion": "filever_01HZY7R4S7",
"createIfMissing": false
}
环境列表响应
{
"success": true,
"data": {
"workspacePath": "C:/workspace/api",
"defaultEnvironment": "dev",
"items": [
{
"id": "env_dev",
"name": "dev",
"scope": "workspace",
"isDefault": true,
"updatedAt": "2026-06-06T10:00:00Z"
}
]
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y5",
"timestamp": "2026-06-06T10:20:30Z"
}
环境保存请求
{
"operationId": "op_save_env_01HZY7R4S8",
"workspacePath": "C:/workspace/api",
"filePath": "C:/workspace/api/.http-client/environments.json",
"contentHash": "sha256:envhash_01HZY7R4S8",
"name": "dev",
"isDefault": true,
"variables": [
{
"name": "baseUrl",
"value": "https://api.example.com",
"scope": "workspace"
}
]
}
历史列表响应
{
"success": true,
"data": {
"page": 1,
"pageSize": 20,
"total": 1,
"items": [
{
"executionId": "exec_01HZY7R4S7M4H4QF3W2K2N4H8A",
"type": "http",
"status": "completed",
"requestName": "List users",
"filePath": "C:/workspace/api/demo.http",
"environment": "dev",
"durationMs": 864,
"startedAt": "2026-06-06T10:20:30Z"
}
]
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y6",
"timestamp": "2026-06-06T10:20:30Z"
}
Mock 规则保存请求
{
"operationId": "op_save_mock_01HZY7R4S9",
"workspacePath": "C:/workspace/api",
"filePath": "C:/workspace/api/.http-client/mocks/users.mock.json",
"contentHash": "sha256:mockhash_01HZY7R4S9",
"name": "Mock list users",
"enabled": true,
"priority": 100,
"tags": ["users", "happy-path"],
"description": "List users success response",
"match": {
"method": "GET",
"path": "/users",
"pathMode": "exact",
"query": {},
"headers": {},
"bodyContains": null
},
"response": {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "[{\"id\":1,\"name\":\"demo\"}]",
"bodyType": "json",
"delayMs": 100,
"templateEnabled": true
}
}
Mock 规则文件保存请求
{
"operationId": "op_save_mock_file_01HZY7R4T0",
"workspacePath": "C:/workspace/api",
"filePath": "C:/workspace/api/.http-client/mocks/users.mock.json",
"contentHash": "sha256:mockfilehash_01HZY7R4T0",
"schemaVersion": 1,
"updatedAt": "2026-06-06T10:20:30Z",
"rules": [
{
"id": "mockrule_users",
"name": "Mock list users",
"enabled": true,
"priority": 100,
"match": {
"method": "GET",
"path": "/users",
"pathMode": "exact"
},
"response": {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "[{\"id\":1,\"name\":\"demo\"}]",
"bodyType": "json",
"delayMs": 100,
"templateEnabled": true
}
}
]
}
Mock 规则文件预览请求
{
"workspacePath": "C:/workspace/api",
"filePath": "C:/workspace/api/.http-client/mocks/users.mock.json",
"mode": "preview",
"rules": [
{
"name": "Mock get user",
"enabled": true,
"priority": 200,
"match": {
"method": "GET",
"path": "/users/:id",
"pathMode": "template"
},
"response": {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"id\":\"{{path.id}}\",\"name\":\"demo\"}",
"bodyType": "json",
"delayMs": 0,
"templateEnabled": true
}
}
]
}
Mock 规则文件预览响应
{
"success": true,
"data": {
"created": 1,
"updated": 0,
"conflicted": 0,
"skipped": 0,
"conflicts": []
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y9",
"timestamp": "2026-06-06T10:20:30Z"
}
Mock Server 状态响应
{
"success": true,
"data": {
"running": true,
"host": "127.0.0.1",
"port": 32190,
"baseUrl": "http://127.0.0.1:32190",
"workspacePath": "C:/workspace/api",
"ruleCount": 3,
"proxyFallbackEnabled": false,
"startedAt": "2026-06-06T10:20:30Z"
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y7",
"timestamp": "2026-06-06T10:20:30Z"
}
Mock 命中日志响应
{
"success": true,
"data": {
"page": 1,
"pageSize": 20,
"total": 1,
"items": [
{
"id": "mockhit_01HZY7R4S7",
"ruleId": "mockrule_users",
"matched": true,
"source": "mock-hit",
"method": "GET",
"path": "/users",
"statusCode": 200,
"durationMs": 101,
"requestSummary": {
"query": {},
"headersCount": 5,
"bodySize": 0
},
"requestedAt": "2026-06-06T10:20:31Z"
}
]
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y8",
"timestamp": "2026-06-06T10:20:31Z"
}
OpenAPI 导入预览响应
{
"success": true,
"data": {
"source": {
"id": "openapi_users",
"name": "Users API",
"sourcePath": "C:/workspace/api/openapi/users.yaml",
"openapiVersion": "3.1.0",
"title": "Users API",
"version": "1.0.0",
"operationCount": 2
},
"targets": {
"requestFilePath": "C:/workspace/api/generated/openapi/users.http",
"mockFilePath": "C:/workspace/api/.http-client/mocks/openapi/users.mock.json"
},
"summary": {
"createdRequests": 2,
"updatedRequests": 0,
"skippedRequests": 0,
"createdMockRules": 2,
"schemaMappings": 2,
"unmappedFields": 1
},
"conflicts": [],
"unmapped": [
{
"fieldPath": "$.components.securitySchemes.ApiKeyAuth",
"reason": "security scheme is recorded but not converted to executable auth config"
}
]
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Y9",
"timestamp": "2026-06-06T10:20:31Z"
}
OpenAPI 同步预览响应
{
"success": true,
"data": {
"sourceId": "openapi_users",
"sourcePath": "C:/workspace/api/openapi/users.yaml",
"strategy": "skip-local-modified",
"summary": {
"created": 1,
"updated": 1,
"deleted": 0,
"skipped": 1,
"conflicted": 1,
"breakingChanges": 1
},
"changes": [
{
"operationId": "listUsers",
"method": "GET",
"path": "/users",
"changeType": "updated",
"breaking": false,
"targetFilePath": "C:/workspace/api/generated/openapi/users.http"
},
{
"operationId": "createUser",
"method": "POST",
"path": "/users",
"changeType": "updated",
"breaking": true,
"targetFilePath": "C:/workspace/api/generated/openapi/users.http"
}
],
"conflicts": [
{
"operationId": "createUser",
"reason": "local request block was modified after last OpenAPI sync",
"targetFilePath": "C:/workspace/api/generated/openapi/users.http",
"requestBlockId": "req_create_user"
}
]
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Z0",
"timestamp": "2026-06-06T10:20:31Z"
}
OpenAPI Schema 校验响应
{
"success": true,
"data": {
"valid": false,
"sourceId": "openapi_users",
"operationId": "listUsers",
"statusCode": 200,
"schemaRef": "#/paths/~1users/get/responses/200/content/application~1json/schema",
"errors": [
{
"path": "$[0].id",
"expected": "integer",
"actual": "string",
"actualSummary": "\"1\""
}
],
"assertion": {
"name": "OpenAPI response schema",
"passed": false,
"errorCode": "SCHEMA_VALIDATION_ERROR"
}
},
"error": null,
"requestId": "req_01HZY7R4S7S0Y73ZJ81EF1Z8Z1",
"timestamp": "2026-06-06T10:20:31Z"
}
附录 C:SQLite 表结构草案
execution_history_index
| 字段 | 类型 | 说明 |
|---|---|---|
id |
TEXT PRIMARY KEY | executionId |
parent_id |
TEXT NULL | 父执行任务 ID |
type |
TEXT NOT NULL | http / batch / chain / sse / websocket / load-test / mock-server |
status |
TEXT NOT NULL | 执行状态 |
request_name |
TEXT NULL | 请求名称 |
request_id |
TEXT NULL | 请求块稳定标识 |
file_path |
TEXT NOT NULL | 请求文件路径 |
workspace_path |
TEXT NULL | 工作区根路径 |
environment |
TEXT NULL | 环境名称 |
duration_ms |
INTEGER NULL | 执行耗时 |
started_at |
TEXT NOT NULL | 开始时间 |
finished_at |
TEXT NULL | 结束时间 |
result_path |
TEXT NULL | 大结果落盘路径 |
result_json |
TEXT NULL | 小结果 JSON 快照 |
created_at |
TEXT NOT NULL | 创建时间 |
索引要求:idx_execution_history_started_at、idx_execution_history_file_path、idx_execution_history_parent_id
execution_event_index
| 字段 | 类型 | 说明 |
|---|---|---|
id |
INTEGER PRIMARY KEY AUTOINCREMENT | 事件索引 ID |
execution_id |
TEXT NOT NULL | 执行任务 ID |
seq |
INTEGER NOT NULL | 事件序号 |
type |
TEXT NOT NULL | 事件类型 |
timestamp |
TEXT NOT NULL | 事件时间 |
payload_path |
TEXT NULL | 大事件载荷落盘路径 |
payload_json |
TEXT NULL | 小事件载荷 JSON |
索引要求:idx_execution_event_execution_seq,并保证同一 execution_id 下 seq 递增唯一
response_cache_index
| 字段 | 类型 | 说明 |
|---|---|---|
id |
TEXT PRIMARY KEY | 缓存记录 ID |
workspace_path |
TEXT NULL | 工作区路径 |
owner_id |
TEXT NOT NULL | 关联执行、事件或历史记录 ID |
kind |
TEXT NOT NULL | response-body / event-payload / history-snapshot |
file_path |
TEXT NOT NULL | 缓存文件路径 |
content_type |
TEXT NULL | 内容类型 |
size_bytes |
INTEGER NULL | 文件大小 |
summary_json |
TEXT NULL | 摘要 JSON |
content_hash |
TEXT NULL | 内容哈希 |
created_at |
TEXT NOT NULL | 创建时间 |
expires_at |
TEXT NULL | 过期时间 |
索引要求:idx_response_cache_owner、idx_response_cache_workspace_kind、idx_response_cache_expires_at
recent_file_cache
| 字段 | 类型 | 说明 |
|---|---|---|
id |
TEXT PRIMARY KEY | 记录 ID |
workspace_path |
TEXT NULL | 工作区路径 |
file_path |
TEXT NOT NULL | 文件路径 |
cursor_line |
INTEGER NULL | 最近光标行 |
cursor_column |
INTEGER NULL | 最近光标列 |
scroll_top |
INTEGER NULL | 最近滚动位置 |
last_opened_at |
TEXT NOT NULL | 最近打开时间 |
索引要求:idx_recent_file_cache_last_opened_at
mock_rule_index
| 字段 | 类型 | 说明 |
|---|---|---|
id |
TEXT PRIMARY KEY | Mock 规则 ID |
workspace_path |
TEXT NOT NULL | 工作区路径 |
file_path |
TEXT NOT NULL | Mock 规则文件路径 |
name |
TEXT NOT NULL | 规则名称 |
enabled |
INTEGER NOT NULL | 是否启用 |
priority |
INTEGER NOT NULL | 匹配优先级 |
tags_json |
TEXT NULL | 标签 JSON |
description |
TEXT NULL | 备注说明 |
match_summary_json |
TEXT NOT NULL | 匹配条件摘要 JSON |
response_summary_json |
TEXT NOT NULL | 响应配置摘要 JSON |
content_hash |
TEXT NOT NULL | 规则文件内容哈希 |
indexed_at |
TEXT NOT NULL | 最近索引时间 |
created_at |
TEXT NOT NULL | 创建时间 |
updated_at |
TEXT NOT NULL | 更新时间 |
索引要求:idx_mock_rule_index_workspace_enabled、idx_mock_rule_index_workspace_priority、idx_mock_rule_index_file_path
mock_hit_logs
| 字段 | 类型 | 说明 |
|---|---|---|
id |
TEXT PRIMARY KEY | 命中日志 ID |
workspace_path |
TEXT NOT NULL | 工作区路径 |
rule_id |
TEXT NULL | 命中的规则 ID,未命中时为空 |
matched |
INTEGER NOT NULL | 是否命中 |
source |
TEXT NOT NULL | 响应来源:mock-hit、mock-miss、proxy-hit、proxy-error |
method |
TEXT NOT NULL | 请求方法 |
path |
TEXT NOT NULL | 请求路径 |
status_code |
INTEGER NOT NULL | 响应状态码 |
duration_ms |
INTEGER NULL | 处理耗时 |
request_summary_json |
TEXT NULL | 请求摘要 JSON |
error_summary |
TEXT NULL | 代理或模板错误摘要 |
requested_at |
TEXT NOT NULL | 请求时间 |
索引要求:idx_mock_hit_logs_workspace_time、idx_mock_hit_logs_rule_id
openapi_source_index
| 字段 | 类型 | 说明 |
|---|---|---|
id |
TEXT PRIMARY KEY | OpenAPI 契约源 ID |
workspace_path |
TEXT NOT NULL | 工作区路径 |
name |
TEXT NOT NULL | 契约源名称 |
source_path |
TEXT NOT NULL | OpenAPI 源文件路径 |
format |
TEXT NOT NULL | json / yaml |
openapi_version |
TEXT NULL | OpenAPI 版本 |
title |
TEXT NULL | API 标题 |
version |
TEXT NULL | API 业务版本 |
operation_count |
INTEGER NOT NULL | operation 数量 |
content_hash |
TEXT NOT NULL | 源文件内容哈希 |
last_synced_at |
TEXT NULL | 最近同步时间 |
indexed_at |
TEXT NOT NULL | 最近索引时间 |
索引要求:idx_openapi_source_workspace、idx_openapi_source_path
openapi_operation_index
| 字段 | 类型 | 说明 |
|---|---|---|
id |
TEXT PRIMARY KEY | operation 索引 ID |
source_id |
TEXT NOT NULL | OpenAPI 契约源 ID |
workspace_path |
TEXT NOT NULL | 工作区路径 |
operation_id |
TEXT NULL | OpenAPI operationId |
method |
TEXT NOT NULL | HTTP 方法 |
path |
TEXT NOT NULL | OpenAPI 路径 |
tags_json |
TEXT NULL | 标签 JSON |
summary |
TEXT NULL | operation 摘要 |
request_file_path |
TEXT NULL | 生成的 .http 文件路径 |
request_block_id |
TEXT NULL | 生成的请求块 ID |
mock_rule_id |
TEXT NULL | 生成的 Mock 规则 ID |
schema_ref |
TEXT NULL | 响应 Schema 引用 |
content_hash |
TEXT NOT NULL | operation 结构摘要哈希 |
indexed_at |
TEXT NOT NULL | 最近索引时间 |
索引要求:idx_openapi_operation_source、idx_openapi_operation_workspace_method_path、idx_openapi_operation_operation_id
schema_migrations
| 字段 | 类型 | 说明 |
|---|---|---|
version |
TEXT PRIMARY KEY | 迁移版本 |
name |
TEXT NOT NULL | 迁移名称 |
applied_at |
TEXT NOT NULL | 执行时间 |
checksum |
TEXT NULL | 迁移文件校验值 |
落盘文件命名规则
-
工作区环境变量文件默认路径格式:
.http-client/environments.json -
工作区项目配置文件默认路径格式:
.http-client/settings.json -
.http-client/environments.json、.http-client/settings.json、.http-client/mocks/**/*.mock.json、.http-client/openapi/sources.json建议纳入 Git 管理 -
SQLite 缓存数据库、响应缓存、事件缓存、命中日志、诊断包默认位于应用数据目录,不建议纳入 Git 管理
-
应用可提供推荐
.gitignore片段,覆盖用户显式选择将缓存目录放在工作区内的情况 -
响应体落盘路径格式:
{appData}/responses/{workspaceHash}/{yyyyMMdd}/{executionId}-{part}.body -
WebSocket / SSE 大事件载荷落盘路径格式:
{appData}/events/{workspaceHash}/{yyyyMMdd}/{executionId}-{seq}.json -
Mock 规则文件默认路径格式:
.http-client/mocks/{mockFileName}.mock.json -
OpenAPI 源映射文件默认路径格式:
.http-client/openapi/sources.json -
OpenAPI 源文件建议保存在工作区可见目录,例如
openapi/{sourceName}.yaml或docs/openapi/{sourceName}.json -
OpenAPI 生成的
.http请求模板默认路径格式:generated/openapi/{sourceName}.http -
OpenAPI 生成的 Mock 规则文件默认路径格式:
.http-client/mocks/openapi/{sourceName}.mock.json -
OpenAPI Schema 校验映射默认随
.http请求块来源标记保存,不额外生成 SQLite 事实源数据 -
Mock 二进制响应体落盘路径格式:
.http-client/mocks/assets/{mockRuleId}.body -
.http-client/mocks/assets/仅用于 Mock 规则引用的静态响应体,不用于普通执行响应缓存或压测采样缓存 -
Mock 规则文件需包含
schemaVersion、rules、updatedAt字段 -
Mock 规则文件加载时需按
schemaVersion进行兼容处理 -
Mock 规则 ID 默认由规则文件相对路径、HTTP 方法、路径匹配表达式和创建时间随机后缀生成,用户修改规则名称不应改变 ID
-
从请求生成 Mock 规则时,若目标文件中已存在同方法同路径规则,默认创建新 ID 并提示可能冲突;用户可选择覆盖已有规则
-
复制 Mock 规则必须生成新 ID,避免跨文件或同文件重复 ID
-
工作区项目配置文件需保存 Mock 代理回退、Mock 命中日志保留策略、默认环境、历史保留策略等配置
-
Mock 命中日志保留策略需写入工作区项目配置文件,默认值为最近
10000条 /7d -
诊断包导出路径格式:
{appData}/diagnostics/diagnostic-{yyyyMMdd-HHmmss}.zip -
SQLite 缓存备份文件格式:
{appData}/backups/cache-{schemaVersion}-{yyyyMMdd-HHmmss}.db
推荐 .gitignore 片段:
# HTTP Client local cache
http-client-cache/
http-client-responses/
http-client-events/
http-client-logs/
http-client-diagnostics/
http-client-backups/
*.db
*.db-*
工作区 JSON 文件示例
.http-client/environments.json 示例:
{
"schemaVersion": 1,
"defaultEnvironment": "dev",
"environments": [
{
"name": "dev",
"variables": {
"baseUrl": "https://api.example.com"
}
}
],
"globals": {}
}
.http-client/settings.json 示例:
{
"schemaVersion": 1,
"defaultEnvironment": "dev",
"history": {
"retentionMaxCount": 1000
},
"mock": {
"proxyFallback": {
"enabled": false,
"upstreamBaseUrl": null
},
"hitLog": {
"retentionMaxCount": 10000,
"retentionDays": 7
}
}
}
.http-client/mocks/users.mock.json 示例:
{
"schemaVersion": 1,
"updatedAt": "2026-06-06T10:20:30Z",
"rules": [
{
"id": "mockrule_users",
"name": "Mock list users",
"enabled": true,
"priority": 100,
"match": {
"method": "GET",
"path": "/users",
"pathMode": "exact"
},
"response": {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyType": "json",
"body": "[{\"id\":1,\"name\":\"demo\"}]",
"delayMs": 100,
"templateEnabled": false
}
}
]
}
.http-client/openapi/sources.json 示例:
{
"schemaVersion": 1,
"sources": [
{
"id": "openapi_users",
"name": "Users API",
"sourcePath": "openapi/users.yaml",
"format": "yaml",
"openapiVersion": "3.1.0",
"title": "Users API",
"version": "1.0.0",
"contentHash": "sha256:openapihash_01HZY7R4T1",
"lastSyncedAt": "2026-06-06T10:20:30Z",
"targets": {
"requestFilePath": "generated/openapi/users.http",
"mockFilePath": ".http-client/mocks/openapi/users.mock.json"
},
"sync": {
"strategy": "skip-local-modified",
"generateRequests": true,
"generateMocks": true,
"enableSchemaValidation": false,
"baseUrlVariable": "baseUrl"
}
}
]
}
迁移要求
-
SQLite 缓存数据库需维护
schema_migrations表,记录已执行迁移版本 -
每次版本升级前需备份 SQLite 缓存数据库文件;工作区 JSON 配置文件按普通文件迁移与 Git 管理处理
-
SQLite 缓存数据库迁移失败时需保留原数据库文件,并提示用户查看日志
-
工作区 JSON 文件迁移需基于
schemaVersion执行,低版本文件可自动迁移,高版本文件默认只读或拒绝写入 -
工作区 JSON 文件迁移前需在同目录生成备份文件,命名格式为
{fileName}.bak-{yyyyMMdd-HHmmss} -
工作区 JSON 文件迁移失败时不得覆盖原文件,并需提示用户查看迁移错误详情
-
SQLite 缓存迁移失败时允许删除并重建索引;删除前应尽量备份原缓存数据库
测试 Fixture 目录结构
-
兼容性用例目录:
compat/{category}/{case}.http -
工作区夹具目录:
fixtures/workspaces/{caseName}/ -
API 示例快照目录:
fixtures/api-snapshots/{apiName}.json -
解析器 golden 快照目录:
fixtures/parser-golden/{caseName}.json -
Mock 规则夹具目录:
fixtures/workspaces/{caseName}/.http-client/mocks/*.mock.json -
OpenAPI 契约夹具目录:
fixtures/workspaces/{caseName}/openapi/*.yaml -
OpenAPI 源映射夹具目录:
fixtures/workspaces/{caseName}/.http-client/openapi/sources.json -
OpenAPI 生成请求夹具目录:
fixtures/workspaces/{caseName}/generated/openapi/*.http -
测试快照需纳入版本管理,运行时生成的响应缓存、日志、SQLite 缓存不得写入 fixture 目录
MVP 任务拆分
后端 MVP 任务
-
MVP-BE-01:完成本地服务启动、端口探测、单实例复用、静态资源托管和运行时元信息文件 -
MVP-BE-02:完成workspace与filestore,支持工作区打开、路径解析、文件读取、原子保存、contentHash和外部变更检测 -
MVP-BE-03:完成.http/.restMVP 解析器,输出稳定 AST、请求块列表、请求命名、注释、错误位置和 parser golden 快照 -
MVP-BE-04:完成环境变量文件.http-client/environments.json的读取、保存、默认环境、变量优先级和未定义变量错误 -
MVP-BE-05:完成 REST API envelope、错误码映射、分页模型、内部 OpenAPI 契约源和前端类型生成输入 -
MVP-BE-06:完成eventbusMVP,支持事件发布、WebSocket 订阅、seq、最终事件和页面刷新后的最终结果快照补拉 -
MVP-BE-07:完成ExecutionMVP 状态机,支持普通 HTTP 请求执行、取消、超时、响应 meta/body、结果固化 -
MVP-BE-08:完成 JavaScript 前置脚本、后置脚本、基础断言、脚本日志和脚本超时 -
MVP-BE-09:完成 SQLiteexecution_history_index、execution_event_index、response_cache_index、recent_file_cache的初始化、写入和重建入口 -
MVP-BE-10:完成后端测试基线,包括 parser golden tests、execution integration tests、API handler tests、script runtime tests
前端 MVP 任务
-
MVP-FE-01:完成应用 shell、三栏布局、路由、全局状态和基础错误提示 -
MVP-FE-02:完成统一 API client、WebSocket event client、错误 envelope 处理、事件去重和断线重连 -
MVP-FE-03:完成文件树、最近文件、文件打开、文件保存、外部变更提示和 Monaco Editor 集成 -
MVP-FE-04:完成当前请求定位、请求块高亮、执行当前请求、取消执行和执行状态展示 -
MVP-FE-05:完成环境切换、变量预览、环境列表、环境变量编辑和默认环境设置 -
MVP-FE-06:完成响应查看器 MVP,支持 Body、Headers、Cookies、Timeline、Logs、Raw / Pretty 展示和大响应截断提示 -
MVP-FE-07:完成历史列表、历史详情、重新执行、打开源文件和定位请求块 -
MVP-FE-08:完成托盘相关前端入口,包括打开页面、退出服务、打开数据目录的状态展示 -
MVP-FE-09:完成前端测试基线,包括编辑器、响应区、环境管理、历史详情和主流程 E2E
MVP 纵向验收切片
-
MVP-VS-01:打开工作区 -> 扫描.http文件 -> 展示请求列表 -> 定位当前请求 -
MVP-VS-02:编辑请求 -> 保存文件 -> 执行当前请求 -> WebSocket 增量展示响应 -> 固化历史 -
MVP-VS-03:创建环境 -> 切换环境 -> 变量预览刷新 -> 使用环境变量执行请求 -
MVP-VS-04:执行带前置脚本、后置脚本和断言的请求 -> 展示脚本日志和断言结果 -
MVP-VS-05:取消长耗时请求 -> 状态进入cancelled-> 历史中保留取消摘要 -
MVP-VS-06:页面刷新或 WebSocket 断开重连 -> 根据executionId恢复最终状态或结果快照 -
MVP-VS-07:外部修改.http或环境文件 -> 应用提示变更 -> 用户重新加载后索引更新
实施步骤
阶段 0:项目骨架
-
初始化 Go module 与后端目录结构
-
初始化 Vue 3 + TypeScript + Vite 前端项目
-
建立前后端开发命令、构建命令、测试命令
-
实现本地服务启动、默认端口、端口探测、静态资源托管
-
建立 SQLite 索引/缓存初始化、
schema_migrations、数据目录结构
阶段 1:MVP 后端
-
实现
.http/.rest基础解析、多请求块、请求命名、注释、错误定位 -
实现变量解析、MVP 变量优先级、未定义变量错误
-
实现本地工作区文件读取、保存、最近文件、外部变更检测
-
实现
Execution状态机、REST 控制面、WebSocket 事件通道 -
实现单请求执行、取消、超时、响应结果固化
-
实现请求历史索引、响应缓存索引、环境变量文件存储、项目配置文件存储
-
实现 JavaScript 前置脚本、后置脚本、基础断言
阶段 2:MVP 前端
-
实现主界面三栏布局、文件树、Monaco Editor、响应区标签页
-
实现当前请求定位、当前请求高亮、执行当前请求
-
实现变量预览、环境切换、错误行列定位
-
实现响应 Body / Headers / Cookies / Timeline / Logs 展示
-
实现请求取消、执行状态展示、WebSocket 事件增量渲染
-
实现历史列表、历史详情、重新执行
-
实现托盘打开页面、退出服务、打开数据目录
阶段 3:MVP 验收
-
建立 MVP 兼容用例集并接入回归测试
-
完成 parser golden tests、executor integration tests、API handler tests
-
完成前端核心组件测试与主流程 E2E 测试
-
验收文件打开、请求执行、取消、历史回看、环境切换、状态恢复主流程
阶段 4:产品目标版本增强
-
实现 Form URL Encoded、Multipart、二进制 Body、外部文件引用
-
实现 Cookie 管理、重定向链、代理、SSL/TLS、客户端证书
-
实现批量执行、链式执行、父子任务历史展示
-
实现 SSE 与 WebSocket 会话视图、消息发送、摘要存储
-
实现轻量压测执行、实时统计、保护阈值、历史报告
-
实现本地 Mock Server、Mock 规则管理、规则优先级、代理回退、命中日志、规则文件保存/重载与从请求/响应生成 Mock
-
实现 curl 导出、Postman collection 导入、OpenAPI 导入与同步
-
实现 OpenAPI diff、生成 Mock 骨架和响应 Schema 校验
-
完善兼容矩阵完整用例集与产品目标版本回归测试
阶段 5:打包发布
-
完成 Windows / macOS / Linux 打包产物
-
完成 SQLite 缓存数据库迁移、工作区 JSON schema 迁移、升级备份、失败回滚验证
-
完成日志目录、诊断包导出、异常退出提示
-
完成平台差异清单与发布说明
.http 文件语法示例
### GET 请求示例
GET https://api.example.com/users
Accept: application/json
###
### POST 请求示例
POST https://api.example.com/users
Content-Type: application/json
Authorization: Bearer {{token}}
{
"name": "John Doe",
"email": "john@example.com"
}
###
### PUT 请求示例
PUT https://api.example.com/users/1
Content-Type: application/json
{
"name": "Jane Doe"
}
###
### 签名请求示例
GET https://api.example.com/orders
Accept: application/json
< {%
const secret = vars.get("secret");
const timestamp = Date.now().toString();
const req = request.get();
const payload = `${req.method}\n${req.url}\n${timestamp}`;
const signature = crypto.hmacSha256Hex(secret, payload);
request.setHeader("X-Timestamp", timestamp);
request.setHeader("X-Signature", signature);
%}
系统托盘功能要求
-
显示应用图标
-
单击打开应用页面
-
右键菜单包含:
-
打开应用页面
-
打开数据目录
-
分隔线
-
退出
-