Files
http-client-app-plan/http-client-app-plan.md

109 KiB
Raw Permalink Blame History

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

文件写入一致性

  • 所有工作区事实源文件保存均需采用原子写入:先写入同目录临时文件,校验成功后再执行原子替换

  • 文件保存失败时不得破坏原文件;失败后需保留可理解错误,并尽量清理临时文件

  • 文件保存请求需携带 baseVersioncontentHash,用于检测保存期间的外部变更

  • 若保存时发现目标文件已被外部修改,应用不得静默覆盖,需提示用户重新加载、另存为或交给 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 分支切换、批量拉取、批量替换等可能产生大量文件变更时,应用应合并通知为一次“工作区发生大量变更”提示,并建议重建索引

  • 文件监听可按平台差异采用不同底层实现,但对上层统一输出:createdupdateddeletedrenamedunknown 五类事件

本地服务与执行模型

本地服务约束

  • 应用以后端本地服务形式运行,前端通过浏览器访问本地页面

  • 本地服务负责提供 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 响应统一包含:successdataerrorrequestIdtimestamp

  • 成功响应中 success=trueerror=null;失败响应中 success=falsedata=null

  • 错误对象至少包含:codemessagedetailslocation

  • 分页查询接口统一使用:pagepageSizetotalitems

  • POST /api/executions 响应至少包含:executionIdstatustype

  • GET /api/executions/:id 响应至少包含:executionIdstatustypestagestartedAtfinishedAterror

  • GET /api/executions/:id/result 响应至少包含完整 ExecutionResult

  • GET /api/history 响应项至少包含:executionIdtypestatusrequestNamefilePathenvironmentdurationMsstartedAt

  • WebSocket 事件统一采用 envelope 结构:typeexecutionIdseqtimestamppayload

  • REST API 示例、OpenAPI 契约与测试快照必须统一使用响应 envelope,不允许同一接口同时存在裸对象响应与 envelope 响应

  • 写入类接口需支持幂等请求标识,推荐使用 Idempotency-Key Header 或请求体 operationId

  • POST /api/executions/:id/cancelPOST /api/mock-files/reloadPOST /api/indexes/rebuild 必须具备幂等语义,重复调用不得产生不一致状态

  • 文件保存类接口需在请求体中携带 baseVersioncontentHash,并在冲突时返回 FILE_CONFLICT

  • 规则级写入接口(如 POST /api/mocksDELETE /api/mocks/:id)需通过显式 filePathmock_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.yamlcomponents.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.yamlopenapi.ymlopenapi.json 文件,产品目标版本支持 OpenAPI 3.0 与 3.1

  • OpenAPI 导入需解析 pathsoperationIdtagsparametersrequestBodyresponsessecurity 的基础结构;security 字段暂不展开执行能力,仅保留为导入报告中的不可执行配置提示

  • 导入后默认按 tags 或路径前缀生成请求分组,并生成可读的 .http 请求模板

  • .http 请求模板需保留 OpenAPI 来源信息,至少包含 sourceIdoperationIdmethodpathschemaRef,用于后续同步定位

  • 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 失效时,系统应优先尝试通过请求块位置重新定位,并在失败时返回可理解错误

  • cursorrequestIdrange 同时出现时,优先级固定为:requestId > range > cursor

变量解析规则

  • 变量解析需区分:全局变量、环境变量、文件内变量、运行时提取变量、链式上下文变量、脚本动态写入变量

  • 变量优先级必须固定并在实现中保持一致,默认推荐顺序为:脚本动态写入变量 > 链式上下文变量 > 文件内变量 > 当前环境变量 > 全局变量

  • 若同名变量在多个层级同时存在,必须以固定优先级解析,不允许根据加载顺序产生不确定结果

  • 未定义变量的处理策略必须显式配置;默认行为为阻断执行并返回 VARIABLE_ERROR

  • 前置脚本写入的变量应在当前请求执行阶段立即生效;后置脚本写入的变量应在后续请求或链式后续步骤中生效

  • 环境切换后应立即重新计算变量解析结果,并同步刷新前端预览

  • 变量语法需与 IntelliJ IDEA HTTP Client 保持一致,默认使用 {{variableName}} 形式

  • 变量解析需支持嵌套引用检测;若出现循环引用,应立即报错并指出引用链

  • 变量值默认按字符串处理;若用于 JSON、Header、Query 等上下文,不隐式推断复杂类型,除非脚本显式构造

实时事件模型

  • WebSocket 事件至少支持:execution.createdexecution.startedexecution.progressexecution.logexecution.response.metaexecution.response.chunkexecution.assertionexecution.completedexecution.failedexecution.cancelled

  • 所有事件均需包含 executionId、事件类型、事件时间戳、最小必要载荷

  • 前端基于事件流增量渲染执行状态、响应内容、脚本输出与断言结果

  • 当事件通道异常断开时,前端需自动尝试重连,并支持按 executionId 补拉最终状态或结果快照

  • WebSocket 重连请求需携带客户端已收到的最新 executionIdlastSeq,后端优先从 execution_event_index 补推缺失事件

  • 若缺失事件已被清理或无法补齐,后端需返回 event.replay.unavailable 事件,前端改为拉取 GET /api/executions/:id/result 最终快照

  • WebSocket 事件 seq 在同一 executionId 内必须单调递增,前端需按 seq 去重和乱序保护

事件背压与高频推送

  • 事件通道需区分关键事件与可合并事件;execution.completedexecution.failedexecution.cancelledexecution.assertion 为关键事件,不得被丢弃

  • execution.progress、压测指标、响应 chunk、脚本日志等高频事件允许合并、采样或限频,但最终结果快照必须保留完整状态摘要

  • 单个前端连接的 WebSocket 待发送队列需设置上限,默认最多缓存 1000 条事件或 10MB 载荷,超过后优先丢弃可合并事件并发送 event.backpressure 告警

  • 响应 chunk 推送默认按 64KB100ms 任一条件触发批量发送,避免小包过多导致 UI 卡顿

  • 压测实时指标默认按 500ms 聚合推送一次;用户界面刷新频率不得高于事件聚合频率

  • 脚本日志默认按行聚合推送,单次执行最多保留最近 1000 条日志,超出后在诊断结果中标记截断

  • 当前端重连后,后端优先按 lastSeq 补发关键事件和最终快照;对已被采样丢弃的进度事件,只保证最终聚合结果可恢复

  • 若 WebSocket 客户端持续消费过慢,后端可关闭该连接并返回可理解关闭原因,前端需自动切换到轮询最终结果快照

执行结果模型

  • 最终结果以 ExecutionResult 形式固化,用于历史记录、页面刷新恢复、问题排查

  • ExecutionResult 至少包含以下部分:summaryrequestresponsetimelineassertionsdiagnostics

  • 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

  • 当用户配置超过默认阈值时,界面需提示并要求显式确认

  • 压测任务取消后应尽快停止新增请求,并等待已发出的请求完成或超时

压测结果模型

  • 压测结果需包含总请求数、成功数、失败数、错误率、总耗时、实际吞吐

  • 压测结果需包含延迟统计:minavgp50p90p95p99max

  • 压测结果需包含状态码分布、错误类型分布、超时数量

  • 压测结果需包含配置快照,便于历史回看时确认当时的并发数、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-hitmock-missproxy-hitproxy-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_ERRORVARIABLE_ERRORSCRIPT_ERRORREQUEST_ERRORASSERTION_ERRORTIMEOUT_ERRORCANCELLEDFILE_CONFLICTSCHEMA_VERSION_UNSUPPORTEDSCHEMA_VALIDATION_ERROROPENAPI_PARSE_ERROROPENAPI_SYNC_CONFLICTINDEX_REBUILD_ERRORMIGRATION_ERRORINTERNAL_ERROR

  • 语法错误、变量错误、脚本错误应尽量返回可映射到编辑器的行列定位信息

脚本与断言模型

脚本运行时边界

  • 请求前置脚本、请求后置脚本、断言统一采用 JavaScript 作为脚本语言

  • 后端采用嵌入式 JavaScript 运行时执行脚本,与 Go 执行器运行在同一进程内

  • 脚本运行时需提供稳定、可控、可测试的内置 API,不依赖浏览器环境

  • 脚本运行时默认不提供任意文件系统访问、任意网络访问、动态模块安装等能力;本条仅定义运行时能力边界

  • 脚本运行时默认不提供浏览器 DOM、windowdocument 等浏览器对象

脚本生命周期

  • 请求执行顺序为:解析请求 -> 变量替换 -> 前置脚本 -> 发送请求 -> 后置脚本 -> 断言 -> 结果固化

  • 批量执行与链式执行中的每个子任务均独立执行上述生命周期

  • 前置脚本可修改最终请求上下文,后置脚本可读取响应并提取变量

签名计算支持

  • 签名计算默认通过后端前置脚本实现,执行时机为变量替换之后、请求发送之前

  • 前置脚本可读取当前请求、环境变量、文件内变量和脚本动态变量,用于构造签名原文

  • 前置脚本可将签名结果写回 Header、Query、Body 或运行时变量

  • 签名计算不得在前端 UI 线程中执行;普通执行、批量执行、链式执行、压测执行均由后端统一完成签名

  • 内置 crypto API 的底层实现应优先使用 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 失败必须生成结构化断言结果,而不是仅输出文本日志

  • 内置 crypto API 至少提供: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_indexexecution_event_indexresponse_cache_indexrecent_file_cachemock_rule_indexmock_hit_logsopenapi_source_indexopenapi_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 编辑、语法高亮、当前请求高亮和错误定位

  • 响应区至少包含 BodyHeadersCookiesTimelineLogs 标签页

  • 响应区需支持普通 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 示例和实施状态,避免文档与实现漂移

  • 若某项验收无法自动化,需在测试记录中说明手工验证步骤、输入数据和观察结果

  • 完成定义固定为:功能可用、错误可理解、状态可恢复、数据不丢失、测试有覆盖、文档已同步

诊断与运维约束

日志与诊断

  • 系统需区分应用日志、执行日志、脚本日志、会话日志,避免所有日志混入同一输出

  • 日志需至少支持 errorwarninfodebug 四级别

  • 每次执行任务需具备可追踪的日志标识,便于通过 executionId 检索相关日志

  • 设置页或托盘菜单需提供“打开日志目录”或等效入口,便于排查问题

  • 用户需能够导出基础诊断信息,至少包含版本号、系统信息、最近错误摘要、最近执行日志索引

  • 日志文件命名格式为 {category}-{yyyyMMdd}.log

  • 执行日志需包含 executionId,便于与历史记录互相定位

  • 诊断包导出格式为 zip,目录结构至少包含 summary.jsonlogs/recent-errors.jsonruntime.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 导入需覆盖 pathstagsoperationIdparametersrequestBodyresponsesservers 的基础映射

  • 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

附录 BAPI 示例 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"
}

附录 CSQLite 表结构草案

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_atidx_execution_history_file_pathidx_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_idseq 递增唯一

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_owneridx_response_cache_workspace_kindidx_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_enabledidx_mock_rule_index_workspace_priorityidx_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-hitmock-missproxy-hitproxy-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_timeidx_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_workspaceidx_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_sourceidx_openapi_operation_workspace_method_pathidx_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}.yamldocs/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 规则文件需包含 schemaVersionrulesupdatedAt 字段

  • 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:完成 workspacefilestore,支持工作区打开、路径解析、文件读取、原子保存、contentHash 和外部变更检测

  • MVP-BE-03:完成 .http / .rest MVP 解析器,输出稳定 AST、请求块列表、请求命名、注释、错误位置和 parser golden 快照

  • MVP-BE-04:完成环境变量文件 .http-client/environments.json 的读取、保存、默认环境、变量优先级和未定义变量错误

  • MVP-BE-05:完成 REST API envelope、错误码映射、分页模型、内部 OpenAPI 契约源和前端类型生成输入

  • MVP-BE-06:完成 eventbus MVP,支持事件发布、WebSocket 订阅、seq、最终事件和页面刷新后的最终结果快照补拉

  • MVP-BE-07:完成 Execution MVP 状态机,支持普通 HTTP 请求执行、取消、超时、响应 meta/body、结果固化

  • MVP-BE-08:完成 JavaScript 前置脚本、后置脚本、基础断言、脚本日志和脚本超时

  • MVP-BE-09:完成 SQLite execution_history_indexexecution_event_indexresponse_cache_indexrecent_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、数据目录结构

阶段 1MVP 后端

  • 实现 .http / .rest 基础解析、多请求块、请求命名、注释、错误定位

  • 实现变量解析、MVP 变量优先级、未定义变量错误

  • 实现本地工作区文件读取、保存、最近文件、外部变更检测

  • 实现 Execution 状态机、REST 控制面、WebSocket 事件通道

  • 实现单请求执行、取消、超时、响应结果固化

  • 实现请求历史索引、响应缓存索引、环境变量文件存储、项目配置文件存储

  • 实现 JavaScript 前置脚本、后置脚本、基础断言

阶段 2MVP 前端

  • 实现主界面三栏布局、文件树、Monaco Editor、响应区标签页

  • 实现当前请求定位、当前请求高亮、执行当前请求

  • 实现变量预览、环境切换、错误行列定位

  • 实现响应 Body / Headers / Cookies / Timeline / Logs 展示

  • 实现请求取消、执行状态展示、WebSocket 事件增量渲染

  • 实现历史列表、历史详情、重新执行

  • 实现托盘打开页面、退出服务、打开数据目录

阶段 3MVP 验收

  • 建立 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);
%}

系统托盘功能要求

  • 显示应用图标

  • 单击打开应用页面

  • 右键菜单包含:

    • 打开应用页面

    • 打开数据目录

    • 分隔线

    • 退出