a4c99b9b0b
- 后端:OpenAPI spec 解析同步、接口分页查询、代理测试(SSRF防护) - 前端:接口列表页、详情对话框(详情/测试双标签)、Token来源选择 - 服务启动自动同步接口数据,支持手动触发同步 - 测试代理路径修复:自动添加 /api 前缀以匹配后端 SSRF 校验 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
6.7 KiB
6.7 KiB
author, created_at, purpose
| author | created_at | purpose |
|---|---|---|
| Peanut | 2026-05-23 | 设计 web-admin 接口管理功能,通过解析 OpenAPI JSON 实现接口发现、管理和测试 |
接口管理功能设计文档
1. 架构概览
Spring Boot 启动时通过 ApplicationRunner 解析本机 /api/v3/api-docs 的 OpenAPI JSON,在事务中全量更新数据库(删除旧数据 → 解析 → 批量插入)。前端从数据库查询接口列表,支持分页、按标签/方法/路径/operationId 搜索。接口测试面板支持三种 Token 来源:当前管理员 Token、手动输入、用户端登录获取并自动保存。后端提供代理测试接口,仅限管理员访问,仅允许转发到本地 /api/* 路径,避免 SSRF。
2. 数据库设计
接口主表 api_endpoint
CREATE TABLE api_endpoint (
id VARCHAR(64) PRIMARY KEY,
path VARCHAR(500) NOT NULL,
method VARCHAR(10) NOT NULL,
operation_id VARCHAR(200),
summary VARCHAR(500),
description TEXT,
tags VARCHAR(500),
deprecated TINYINT(1) DEFAULT 0,
request_schema JSON,
response_schema JSON,
create_by VARCHAR(64),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_by VARCHAR(64),
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
is_deleted TINYINT(1) DEFAULT 0,
remarks VARCHAR(500),
UNIQUE INDEX idx_operation_id (operation_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
参数表 api_param
CREATE TABLE api_param (
id VARCHAR(64) PRIMARY KEY,
endpoint_id VARCHAR(64) NOT NULL,
param_type VARCHAR(20) NOT NULL,
name VARCHAR(100) NOT NULL,
required TINYINT(1) DEFAULT 0,
param_type_def VARCHAR(50),
description VARCHAR(500),
default_value VARCHAR(200),
enum_values JSON,
example VARCHAR(500),
INDEX idx_endpoint (endpoint_id),
FOREIGN KEY (endpoint_id) REFERENCES api_endpoint(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
说明:实体类继承项目已有的 BaseEntity(含 id、createBy、createTime、updateBy、updateTime、isDeleted、remarks),使用 IdType.ASSIGN_UUID 生成 UUID 主键。
3. 后端服务设计
新增文件
| 文件 | 职责 |
|---|---|
entity/ApiEndpoint.java |
继承 BaseEntity |
entity/ApiParam.java |
继承 BaseEntity |
mapper/ApiEndpointMapper.java |
BaseMapper |
mapper/ApiParamMapper.java |
BaseMapper |
dto/request/ApiEndpointListRequest.java |
继承 BasePageRequest,添加 method、tags 过滤 |
dto/response/ApiEndpointItemResponse.java |
列表项 |
dto/response/ApiEndpointDetailResponse.java |
详情 + 参数列表 |
dto/request/ApiTestProxyRequest.java |
代理测试入参 |
service/ApiEndpointService.java |
解析 OpenAPI JSON、同步、查询 |
service/ApiEndpointSyncRunner.java |
@Component + ApplicationRunner,启动时触发 |
controller/ApiEndpointController.java |
路由前缀 /endpoint |
controller/ApiTestProxyController.java |
路由前缀 /endpoint/test,管理员专用 |
同步逻辑(ApiEndpointService.syncFromOpenApi())
- 通过 RestTemplate 请求
http://127.0.0.1:{port}/api/v3/api-docs(port 从配置文件读取) - 若请求失败,记录 WARN 日志,不阻断启动
@Transactional包裹:DELETE FROM api_param → DELETE FROM api_endpoint- 遍历
paths→method→ 解析每个 endpoint - 提取 tags、summary、description、operationId、requestSchema、responseSchema
- 从
parameters数组解析参数列表(query/path/header/cookie) - 从
requestBody.content解析 body schema $ref展开为内联 schema,最大展开深度 10 层- 批量插入 endpoint → 批量插入 param
后端接口(无 /api 前缀,通过网关转发)
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| POST | /admin/endpoint/list | 分页查询,关键词同时搜索 path/summary/operation_id | 管理员 |
| GET | /admin/endpoint/detail | 查询详情 + 参数列表 | 管理员 |
| POST | /admin/endpoint/sync | 手动触发同步,同步耗时较长,返回 task ID | 管理员 |
| POST | /admin/endpoint/test | 代理测试请求,仅允许 /api/* 路径 | 管理员 |
代理测试安全控制
- 仅允许转发到
/api/*路径,拒绝其他 URL(SSRF 防护) - 仅管理员可访问(AdminAuthInterceptor 拦截 /admin/**)
- 默认 30s 超时,超时返回明确错误信息
- 非 JSON 响应限制展示前 2000 字符,HTML 内容做转义处理
同步接口异步化
手动同步(/admin/endpoint/sync)采用 @Async 异步执行,返回 { taskId: "xxx" },前端通过轮询 /admin/endpoint/sync/status/{taskId} 获取同步进度和结果。ApplicationRunner 的启动同步同样异步,不阻塞应用启动。
4. 前端页面设计
菜单位置
在现有 开发工具 分组下新增 "接口管理" 子菜单。
接口列表页
- 搜索条件:关键词(覆盖 path、summary、operation_id)、HTTP 方法下拉、标签下拉
- 表格列:方法(颜色标签区分)、路径、简述、标签、更新时间
- 操作列:[详情] 按钮
- 顶部:[手动同步] 按钮(触发后显示同步进度提示)
接口详情/测试弹窗
点击"详情"弹出对话框,包含两个标签页:
详情标签:
- 路径、方法、描述
- 参数列表表格(类型、名称、必填、描述、示例)
- 响应结构 JSON 展示
测试标签:
- Token 来源选择(单选):
- 使用当前管理员 Token(默认)
- 手动输入文本框
- 用户端登录获取(输入手机号/验证码,成功后自动保存 Token 到 localStorage)
- 参数表单:根据接口参数自动生成输入框
- [发送请求] 按钮
- 响应结果区域:状态码、耗时、JSON 格式化展示
5. 错误处理与边界情况
| 场景 | 处理方式 |
|---|---|
/v3/api-docs 请求失败 |
记录 WARN 日志,不阻断启动,提供手动同步 |
| 同步中途异常 | @Transactional 回滚,下次同步全量替换 |
| 数据库为空 | 前端显示空状态提示 + 手动同步按钮 |
| 测试代理超时 | 返回 Result.error("代理请求超时(30s),目标接口可能响应过慢或不可达") |
| 非 JSON 响应 | 展示前 2000 字符,HTML 转义,二进制返回类型提示 |
| Token 保存 | 管理员 Token 走现有机制,手动 Token 仅内存使用,用户端 Token 存 localStorage |
$ref 循环引用 |
最大展开深度 10 层,超限保留 $ref 并提示 |
| 文件上传接口 | 本期不支持,后续迭代 |