Răsfoiți Sursa

docs(dev-rule): 补充 Swagger 泛型返回类型文档化规范

- 新增关于 Swagger 注解使用的规定,明确泛型返回类型的文档化方式
- 补充 Controller 方法中使用 @Operation 和 @ApiResponse 的示例
- 增加 DTO/VO 字段注解说明,提升文档可读性
- 添加分页、集合等复杂泛型的处理建议
- 强调文档与实现同步的重要性,作为代码审查项
- 提供依赖版本管理建议,确保文档生成一致性
mcbaiyun 1 lună în urmă
părinte
comite
db6e2b82ea

+ 17 - 0
docs/DevRule/01-代码风格指南.md

@@ -169,6 +169,23 @@ String tokenHeader = request.getHeader("token");
 - 在控制器/服务中尽量使用 `AuthPrincipal`/`currentUserId` 作为当前请求用户的来源,而不是重新解析 token。
 - 如果文档中的旧条目(如"自定义异常继承 Exception")与上面实际实现冲突,以代码为准并及时修正文档。
 
+## Swagger 注解与接口文档约定(补充)
+
+为保证生成的 API 文档准确且易读,接口方法应遵循以下注解约定:
+
+- 对于返回泛型包装类(如 `R<T>`、`ResponseEntity<T>`)的接口,在 Controller 方法上显式使用 `@Operation` / `@ApiResponse` 并通过 `@Content` + `@Schema(implementation = Xxx.class)` 指定实际返回类型。避免依赖 Swagger 在运行时推断泛型。 
+- 对每个公开响应字段在 DTO/VO 中使用 `@Schema(description = "...")` 注解,确保字段说明在文档中显示。
+- 例子(局部示例):
+  ```java
+  @Operation(summary = "获取用户")
+  @ApiResponse(responseCode = "200", description = "OK",
+      content = @Content(schema = @Schema(implementation = UserResponse.class)))
+  public R<?> getUser(...) { ... }
+  ```
+
+此约定应作为代码审查项之一,确保接口文档与实现同步。 
+
+
 ---
 
 文档已根据仓库中实际实现同步关键点,若需要我可以:

+ 24 - 0
docs/DevRule/03-API设计规范.md

@@ -132,6 +132,30 @@
    }
    ```
 
+### Swagger / OpenAPI:泛型返回类型的文档化(补充)
+
+说明:当接口返回自定义泛型包装类(例如项目中的 `R<T>`)或框架泛型类型(如 `ResponseEntity<T>`、`Page<T>`)时,Swagger 无法自动推断出泛型参数的具体类型,导致文档中 `data` 或 `records` 字段的结构缺失。为保证 API 文档完整、可读,建议在 Controller 层显式声明返回数据的实现类型。
+
+要点总结:
+- 在 Controller 方法上使用 `@Operation` / `@ApiResponse` 配合 `@Content` 和 `@Schema(implementation = XXX.class)` 明确指定返回的具体类型。这样 Swagger UI / Knife4j 能正确展示 data 中对象的字段。 
+- 对于分页、集合等复杂泛型,创建专门用于文档说明的 VO(例如 `UserBindingPageResult`),并在注解中引用该 VO。 
+- 为常见的 HTTP 状态码均添加 `@ApiResponse` 注解(200/400/401/403/404/500 等),提高文档的完整性。
+
+示例(参考实现):
+```java
+@Operation(summary = "检查用户绑定关系")
+@PostMapping("/check")
+@ApiResponse(responseCode = "200", description = "OK",
+   content = @Content(mediaType = "application/json",
+      schema = @Schema(implementation = CheckUserBindingResponse.class)))
+public R<?> check(@RequestBody CheckUserBindingRequest req) { ... }
+```
+
+兼容与流程建议:
+- 在编写或修改接口时同时更新注解,确保 API 文档与实际返回一致。 
+- 若项目采用自动化契约测试或 API 文档校验,将 api-docs 的输出加入到 CI 校验流程中以防止文档失真。
+
+
 ## 安全考虑
 1. **输入验证**:使用Bean Validation注解
 2. **SQL注入防护**:使用MyBatis-Plus预编译

+ 15 - 0
docs/DevRule/04-测试规范.md

@@ -75,6 +75,21 @@
 - 避免在测试中使用硬编码的外部依赖。
 - 定期review测试代码,确保其有效性。
 
+### API 文档与契约测试(补充)
+
+目的:确保生成的 Swagger/OpenAPI 文档正确地体现接口契约,尤其是当接口返回泛型包装类(如 `R<T>`、分页 `Page<T>`)时,文档应显示具体字段结构。
+
+建议测试项:
+- 文档结构断言:使用集成测试在 `/v3/api-docs` 或 Knife4j 的 JSON 输出上断言特定接口的 schema 中包含预期字段(例如断言某接口的 `data` 类型为 `CheckUserBindingResponse` 的 schema)。
+- 注解覆盖验证:在变更 Controller 的返回类型或 VO 后,运行文档生成并比对变更,确保 `@ApiResponse` / `@Schema` 注解的声明能被正确解析。
+- CI 校验:把对 `/v3/api-docs` 的基本断言纳入 CI(如果团队接受),避免接口实现与文档脱节。
+
+示例(测试思路):
+1. 启动应用上下文并请求 `/v3/api-docs`,获取 JSON。
+2. 解析 JSON,定位目标接口的 responses -> 200 -> content -> application/json -> schema -> $ref,并解析该 schema 对应的定义。
+3. 断言 schema 定义中列出了预期字段,例如 `exists`、`bindingType` 等。
+
+
 ### 关于长整型 ID 的测试
 
 目的:验证 API 在面对超过 JavaScript 安全整数范围(> 2^53-1)的 ID 时,前端与后端之间不会因为精度丢失而导致 CRUD 操作失败或数据不一致。

+ 30 - 0
docs/DevRule/05-依赖管理规范.md

@@ -136,3 +136,33 @@
 - 引入映射库后,应在 Code Review 与 CI 中加入对生成代码的检查,确保映射规则(如 id 字段转为字符串)在 mapper 接口中有明确配置。
 - 若不引入映射库,请在 `01-代码风格指南.md` 中保留映射示例(手动 copy + 显式 id.toString())作为团队约定。
 
+## 与 API 文档相关的依赖(补充)
+
+说明:生成正确的 Swagger/OpenAPI 文档依赖于项目中所使用的文档库及其兼容版本(例如 `springdoc-openapi` 与 Knife4j)。泛型返回类型在文档中不被正确解析,通常靠注解显式声明解决,但依赖版本也会影响行为。建议:
+
+- 保持 `springdoc-openapi` 与 `knife4j` 的版本在依赖管理中统一声明,并记录推荐版本(当前项目使用 `knife4j-openapi3-jakarta-spring-boot-starter:4.4.0`,请参考与之兼容的 `springdoc-openapi` 版本)。
+- 若使用 `springdoc-openapi`,必要时在配置中通过 `OpenApiCustomiser` 或 `ModelConverters` 注册额外模型(`additionalModels`)以帮助生成器解析自定义类型。 
+- 依赖示例与说明需写入本文件,以便团队在引入或升级文档依赖时遵循统一版本策略。 
+
+示例(pom 片段说明思路,仅供参考):
+```xml
+<!-- 统一在 <properties> 中声明文档组件版本 -->
+<properties>
+  <springdoc.version>1.6.14</springdoc.version>
+  <knife4j.version>4.4.0</knife4j.version>
+</properties>
+
+<!-- 依赖管理区 -->
+<dependency>
+  <groupId>org.springdoc</groupId>
+  <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+  <version>${springdoc.version}</version>
+</dependency>
+<dependency>
+  <groupId>com.github.xiaoymin</groupId>
+  <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
+  <version>${knife4j.version}</version>
+</dependency>
+```
+
+