# API 变更检测 — 分析与设计 在现有 **类变更检测**(`class-checker.jar`)基础上,扩展 **API 路径变更** 与 **API 参数变更** 两类能力。通知渲染参考 [`11.py`](./11.py)。 --- ## 一、用 JavaParser 做方便吗? **结论:方便,且与现有技术栈一致。** | 维度 | 评估 | |------|------| | 技术栈 | `class-checker` 已依赖 `javaparser-symbol-solver-core 3.25.10`,`EndpointParser` 已在用 | | 路径解析 | `@RequestMapping` / `@GetMapping` 等注解 + 类级 path 拼接 — **已实现** | | HTTP 方法 | Mapping 注解读取 — **已实现** | | 参数解析 | 方法 `Parameter` + `@RequestBody` / `@PathVariable` / `@RequestParam` 注解 — **需扩展** | | DTO 字段 diff | `@RequestBody` 的 Dto 一级字段 — 可复用 `ClassFieldParser` + `FieldDiffEngine` | | 跨提交对比 | `git show oldSha:path` / `newSha:path` + AST 对比 — 与类变更相同模式 | JavaParser **擅长** 注解驱动的 Spring MVC 声明式接口;**不擅长** 运行时动态路由、非注解配置(如 `WebMvcConfigurer` 手动注册)。 --- ## 二、与现有代码的关系 ``` 现有(类变更) 待扩展(API 变更) ───────────────── ───────────────── GitChangeScanner ────────► Git 扫描 Controller/*.java 变更 EndpointParser(索引) ────────► EndpointSnapshotParser(含参数明细) FieldDiffEngine ────────► 复用:@RequestBody Dto 字段 diff ImpactAnalyzer ────────► (类变更专用,API 变更不直接用) WeComNotifier ────────► ApiChangeNotifier(新,参考 11.py) ``` 当前 `ApiEndpoint` 仅含:`httpMethod`、`uri`、`paramTypes`(类型简单名集合)、`returnTypes`,**不足以做参数级 diff**,需扩展为 `ApiEndpointSnapshot`(含每个参数的 name、type、source、required、description 等)。 --- ## 三、检测能力拆分 ### 3.1 API 路径变更(功能 1) | 场景 | 识别方式 | 通知模版 | |------|----------|----------| | 新增接口 | 新 commit 有、旧 commit 无(同 Controller 方法指纹) | [`api-path-change.md`](./api-path-change.md) · 新增接口 | | 删除接口 | 旧有、新无 | 删除接口 | | 修改路径 | 类级/方法级 `@RequestMapping` path 变化,HTTP 方法不变 | 修改路径 | | 修改请求方式 | 同 URI(或同方法指纹)HTTP 方法变化 | [`api-method-change.md`](./api-method-change.md) | **方法指纹建议**(用于跨 commit 匹配同一接口): ``` controller源文件 + 方法名(不含参数信息;增删参/改类型等由 ParameterDiffEngine 检测) ``` 仅 URI 匹配在「改路径」场景会失效,需指纹辅助。 ### 3.2 API 参数变更(功能 2) | 参数来源 | 检测内容 | 展示分组 | |----------|----------|----------| | `@RequestBody` Dto | Dto **一级字段** 增删改/重命名/类型 | 类对象变更 | | `@PathVariable` | 名称、类型、是否新增/删除 | 普通参数变更 | | `@RequestParam` | 名称、类型、required | 普通参数变更 | | 无注解简单参数 | 视项目规范决定是否纳入 | 待确认 | **排除**(参考 11.py / comparator 惯例):`HttpServletRequest`、`HttpServletResponse`、`BindingResult`、`Principal`、`Model`、`ModelMap` 等框架注入参数。 模版见 [`api-param-change.md`](./api-param-change.md)。 --- ## 四、建议架构(Java 实现) ``` .gitea/checker/src/main/java/com/aicheck/ ├── api/ │ ├── ApiCheckMain.java # 可选:独立 CLI 或并入 ClassCheckMain │ ├── scanner/ │ │ └── ControllerChangeScanner.java # git diff 筛 Controller 文件 │ ├── parser/ │ │ └── EndpointSnapshotParser.java # 扩展 EndpointParser,输出完整快照 │ ├── analyzer/ │ │ ├── EndpointDiffEngine.java # 路径/方法/增删对比 │ │ └── ParameterDiffEngine.java # 参数 + Body Dto 字段对比 │ ├── model/ │ │ ├── EndpointSnapshot.java │ │ ├── EndpointChangeReport.java # 对齐 11.py EndpointChangeReport │ │ └── ParameterChange.java # 对齐 11.py ParameterChange │ └── notify/ │ └── ApiChangeNotifier.java # 对齐 11.py 三类模版 ``` **流程**: 1. `git diff --name-only oldSha newSha` 筛 `endpoint_scan.controllers` 下 `.java` 2. 对每个变更 Controller,分别读取 old/new 源码 3. `EndpointSnapshotParser` 解析两端快照 4. `EndpointDiffEngine` 产出路径/方法/增删报告 5. URI+方法未变的接口 → `ParameterDiffEngine` 产出参数报告 6. `ApiChangeNotifier` 按类型发企微(路径/方法/参数分条发送,与 11.py 一致) --- ## 五、模版文件 | 文件 | 对应 11.py | 场景 | |------|------------|------| | [api-path-change.md](./api-path-change.md) | `build_path_change_markdown` | 新增 / 删除 / 修改路径 | | [api-method-change.md](./api-method-change.md) | `build_method_change_markdown` | 修改 HTTP 方法 | | [api-param-change.md](./api-param-change.md) | `_format_endpoint_block` | URI+方法不变,仅参数变 | | [11.py](./11.py) | 参考实现(Python + comparator) | 通知渲染逻辑 | --- ## 六、配置扩展建议(`config.yaml`) ```yaml api_check: enabled: true endpoint_scan: controllers: - jnpf-ftb/jnpf-ftb-biz/src/main/java feign_apis: [] # 是否纳入 Feign,待确认 exclude_framework_params: true body_dto_field_depth: 1 # @RequestBody 只 diff 一级字段 ``` 可与 `class_check` 共用 `wecom` 配置。 --- ## 七、工作量粗估 | 模块 | 难度 | 说明 | |------|------|------| | EndpointSnapshotParser | 中 | 扩展参数注解解析 | | EndpointDiffEngine | 中 | 方法指纹 + 路径/方法对比 | | ParameterDiffEngine | 中高 | Body Dto 复用 FieldDiffEngine;普通参数 diff | | ApiChangeNotifier | 低 | largely 翻译 11.py | | CI / 配置 / 联调 | 低 | 扩展 workflow 或合并 Main | 整体:**可行,约 3–5 个核心类 + 1 个 Notifier**,与类变更检测复用 Git + JavaParser + 企微基础设施。 --- ## 八、实现状态(已并入 `class-checker.jar`) | 模块 | 包路径 | 状态 | |------|--------|------| | 配置 | `AppConfig` + `config.yaml` `api_check` | ✅ | | 扫描 | `api.scanner.ApiFileChangeScanner` | ✅ | | 解析 | `api.parser.EndpointSnapshotParser`、`NestedDtoFieldParser` | ✅ | | 分析 | `api.analyzer.ApiChangeAnalyzer`、`EndpointDiffEngine`、`ParameterDiffEngine` | ✅ | | 通知 | `api.notify.ApiChangeNotifier`(路径/方法/参数分条) | ✅ | | 编排 | `ClassCheckMain`(类变更与 API 变更独立执行) | ✅ | | 公共 | `common.MarkdownStyles`、`common.WeComMarkdownSender` | ✅ | **已确认策略**:并入同一 jar;含 Feign;含请求方式变更;嵌套 Dto 字段;对齐类变更通知规范;分条发送;路径+参数同改拆两条;不含 LLM。