1. 概述
在这个教程中,我们将讨论Swagger的@Operation
和@ApiResponse
注解之间的主要区别。
2. 使用Swagger进行描述性文档
创建REST API时,为其编写适当的规范同样重要。此外,规范应该易于阅读、理解,并提供所有关键信息。而且,文档应描述对API所做的任何更改。手动创建REST API文档既耗时又累人。幸运的是,工具如Swagger可以帮助我们完成这个过程。
Swagger是一套围绕OpenAPI规范构建的开源工具,它能帮助我们设计、构建、文档化和使用REST API。
Swagger规范是为REST API文档的标准。使用Swagger规范,我们可以描述整个API,包括公开的端点、操作、参数、认证方法等。
Swagger提供了各种注解,帮助我们文档化REST API。更重要的是,它提供了@Operation
和@ApiResponse
注解来为REST API文档化响应。在本教程的剩余部分中,我们将使用下面的控制器类,看看如何使用这些注解:
@RestController
@RequestMapping("/customers")
class CustomerController {
private final CustomerService customerService;
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
@GetMapping("/{id}")
public ResponseEntity<CustomerResponse> getCustomer(@PathVariable("id") Long id) {
return ResponseEntity.ok(customerService.getById(id));
}
}
3. @Operation
@Operation
注解用于描述单个操作。操作是路径和HTTP方法的独特组合。
此外,使用@Operation
,我们可以描述REST API调用成功的结果。换句话说,我们可以使用此注解来指定一般的返回类型。
让我们将注解添加到我们的方法中:
@Operation(summary = "Gets customer by ID",
description= "Customer must exist")
@GetMapping("/{id}")
public ResponseEntity<CustomerResponse> getCustomer(@PathVariable("id") Long id) {
return ResponseEntity.ok(customerService.getById(id));
}
接下来,我们将详细介绍@Operation
中的某些常用属性。
3.1. summary
属性
summary
属性是必需的,包含操作的摘要字段。简单来说,它提供了操作的简短描述。然而,我们应该确保这个参数长度不超过120个字符。
这是我们在@Operation
注解中定义summary
属性的方式:
@Operation(summary= "Gets customer by ID")
3.2. description
属性
使用description
,我们可以提供有关操作的更多详细信息。例如,我们可以放置一个文本来描述端点的限制:
@Operation(summary= "Gets customer by ID", description= "Customer must exist")
3.3. hidden
属性
hidden
属性表示此操作是否隐藏。
4. @ApiResponse
通常,我们使用HTTP状态码返回错误。我们可以使用@ApiResponse
注解来描述操作可能的具体响应。
虽然@Operation
注解描述了一个操作和一般的返回类型,而@ApiResponse
注解则描述了其他可能的返回代码。
此外,该注解可以应用于方法级别和类级别。如果类级别的注解已经定义了与方法级别相同的代码的@ApiResponse
,那么类级别注解将不会解析。换句话说,方法注解优先于类注解。
无论我们有一个还是多个响应,都应该在@ApiResponses
注解内使用@ApiResponse
注解。直接使用此注解将不会被Swagger解析。
现在,让我们在方法上定义@ApiResponses
和@ApiResponse
注解:
@ApiResponses(value = {
@ApiResponse(responseCode = 400, description = "Invalid ID supplied"),
@ApiResponse(responseCode = 404, description = "Customer not found")})
@GetMapping("/{id}")
public ResponseEntity<CustomerResponse> getCustomer(@PathVariable("id") Long id) {
return ResponseEntity.ok(customerService.getById(id));
}
我们也可以使用注解来指定成功响应:
@Operation(summary = "Gets customer by ID", description = "Customer must exist")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Ok", content =
{ @Content(mediaType = "application/json", schema =
@Schema(implementation = CustomerResponse.class)) }),
@ApiResponse(responseCode = "400", description = "Invalid ID supplied"),
@ApiResponse(responseCode = "404", description = "Customer not found"),
@ApiResponse(responseCode = "500", description = "Internal server error", content =
{ @Content(mediaType = "application/json", schema =
@Schema(implementation = ErrorResponse.class)) }) })
@GetMapping("/{id}")
public ResponseEntity<CustomerResponse> getCustomer(@PathVariable("id") Long id) {
return ResponseEntity.ok(customerService.getById(id));
}
现在,让我们看看@ApiResponse
中的一些属性。
4.1. responseCode
和 description
属性
responseCode
和description
属性都是@ApiResponse
注解中的必需参数。重要的是,我们不能为具有相同代码属性的多个@ApiResponse
定义。
message
属性通常包含与响应关联的人可读消息:
@ApiResponse(responseCode = 400, message = "Invalid ID supplied")
4.2. content
属性
有时,端点使用不同的响应类型。例如,我们可以为成功响应和错误响应使用不同的类型。我们可以使用可选的content
属性通过关联响应类作为模式来描述它们。
首先,我们定义一个在发生内部服务器错误时返回的类:
class ErrorResponse {
private String error;
private String message;
// getters and setters
}
其次,为内部服务器错误添加一个新的@ApiResponse
:
@Operation(summary = "Gets customer by ID", description = "Customer must exist")
@ApiResponses(value = {
@ApiResponse(responseCode = "400", description = "Invalid ID supplied"),
@ApiResponse(responseCode = "404", description = "Customer not found"),
@ApiResponse(responseCode = "500", description = "Internal server error",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class)) }) })
@GetMapping("/{id}")
public ResponseEntity<CustomerResponse> getCustomer(@PathVariable("id") Long id) {
return ResponseEntity.ok(customerService.getById(id));
}
5. @Operation
和 @ApiResponse
的差异
总结一下,以下是@Operation
和@ApiResponse
注解的主要差异:
@Operation
@ApiResponse
用于描述操作
用于描述操作可能的响应
用于成功响应
用于成功和错误响应
只能在方法级别定义
可以在方法或类级别定义
可以直接使用
只能在@ApiResponses
注解内使用
6. 结论
在这篇文章中,我们了解了@Operation
和@ApiResponse
注解的区别。
如往常一样,示例代码可在GitHub上找到:GitHub。