我正在使用SpringDoc记录一个现有的基于Java的API。我们所有的API都有一个通用的响应对象(如下所示),它有两个字段,一个是状态,另一个是包含实际结果的对象。
class MyResponse {
private String status;
private Object result;
.........
}
是否有一种方法允许我根据调用的API来记录结果对象的实际运行时类型?例如,如果我的调用是getCustomer()API,我希望为Customer结果对象生成文档;如果我的呼叫是getProduct()API,我希望生成Product结果对象的文档。
您应该使用@ApiResponse
来记录将返回的数据类型。以下是您感兴趣的注释-
-
@ApiResponses
-表示方法可能返回的响应数组,包括错误响应。公共响应集可以在类级别指定,而特定的一次可以在方法级别提供。value
-一个@ApiResponse
的数组
-
@ApiResponse
-用于描述方法可能返回的特定响应。不能用于类级别。responseCode
-表示响应代码的String
值,如"200"
、"401"
等description
-响应的描述。通常是HTTP状态消息,如"OK"
、"Unauthorized"
等content
-描述将由该方法返回的内容。有关详细信息,请参阅@Content
注释
重要-
401 - Unauthorized
等响应可能不会返回任何信息。在这种情况下,内容的首字母应为空@Schema
,如下所示。@ApiResponse(responseCode = "401", description = "Unauthorized", content = {@Content(schema = @Schema())})
-
@Content
-描述将由该方法作为响应返回的内容。mediaType
-指定API将返回的对象类型如果返回有效响应,则必须指定。可以在类级别定义。例如CCD_ 19或CCD_ 20等schema
-将作为方法的响应返回的@Schema
对象。有关更多详细信息,请参阅@Schema
-
@Schema
-描述将作为响应返回的模式对象(POJO,甚至可以是基元数据类型,相应地设置mediaType
)。不指定任何属性意味着对象不会返回任何属性(通常与错误响应一起使用)。implementation
-将作为方法的响应返回的类对象的名称。默认为Void.class
-
@Parameter
-用于带有其他注释的方法参数,如@RequestParam
、@PathVariable
等。description
-描述所需的参数required
-Boolean
值,指定参数是可选的还是强制的。默认为参数指定的值,如@RequestParam
、@PathVariable
等
-
@io.swagger.v3.oas.annotations.parameters.RequestBody
-描述处理请求的方法所需的请求正文。description
-提供对请求正文的描述required
-指定正文是可选的还是强制的Boolean
值。默认为true
记住
- 虽然也可以使用
@Parameter
来代替它,但在这种情况下,所有的类obejct都通过引用来解析,因此只保留最后描述的一个 - 这个
@RequestBody
与Spring提供的不同,因此必须与@org.springframework.web.bind.annotation.RequestBody
一起使用
下面是一个控制器的示例,其中包含文档所需的注释。
@RestController
// the "produces" attribute in @RequestMapping can be used to specify the default mediaType.
@RequestMapping(path = "/api/v1/user/", produces = { MediaType.APPLICATION_JSON_VALUE })
// Defines common tag for all the operartions handled by this class
@Tag(name = "User Operations", description = "APIs for operation on User")
// API responses that might be returned by all the methods in this class
@ApiResponses(value = {
@ApiResponse(responseCode = "400", description = "Bad Request", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserErrorResponse.class))}),
@ApiResponse(responseCode = "500", description = "Internal Server Error", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserErrorResponse.class))})
})
public class UserController {
// POST Method
// Swagger Annotations
@Operation(summary = "Create User", description = "User-ID is generated and maintained by the service.", tags = {"User Operations"})
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "Created", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserCreateResponse.class))}),
@ApiResponse(responseCode = "409", description = "User Collision Detected", content = {@Content(schema = @Schema())})
})
// Spring Annotations
@ResponseStatus(code = HttpStatus.CREATED)
@PostMapping(value = "/patients", consumes = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<MyResponse> createUser(
// Note the two @RequestBody from Swagger and Spring
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "A request to create user object") @Valid @RequestBody final User user)
{
...
}
// GET Method
// Swagger Annotations
@ApiResponses(value = {
@ApiResponse(
responseCode = "200", description = "OK",
// Note the way content is defined for valid objects
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = User.class))})),
@ApiResponse(
responseCode = "404", description = "Not Found",
// Note the way, when no object is returned
content = {@Content(schema = @Schema())})),
})
// Spring Annotations
@ResponseStatus(HttpStatus.OK)
@GetMapping(value = "")
public MyResponse getUser(
@Parameter(required = false, description = "Search by firstName") @RequestParam(required = false) String firstName)
{
...
}
}
听起来应该使用泛型类型参数而不是Object类型。问题是,Springdoc只知道你告诉它什么,你可以像Debargha建议的那样通知它。然而,这可能会变得非常混乱,而且不太容易维护。幸运的是,它有一个自动检测功能,可以隔离到不同的基本API路径(即".API/v1/产品../.."),这确实考虑了父类,并正确地为它们生成模式。
昨天我遇到了类似的问题,并找到了一个非常紧凑的解决方案,用于为复杂、通用和/或嵌套的java类型声明OpenApi模式。完整描述如下:Open Api Documentation 的通用Java类型和嵌套数组注释
TL:DR;是在@OpenAPIDefinition注释类中注册一个自定义的openApiGroup,然后创建一个标准的SpringBoot@Configuration类。在第二个类中,您放置了空类,用@Schema(desc.optional)进行注释,扩展了MyResponse、MyResponse<列表>等等。任何从自定义组的路径扩展的端点,现在都可以使用这些组合作为返回类型——不是空类的名称,而是实际的东西(例如List)和springdoc会拾取它。