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.
The annotation is used to describe a single operation. An operation is a unique combination of a path and an HTTP method.
Additionally, using , we can describe the result of a successful REST API call. In other words, we can use this annotation to specify the general return type.
Let’s add the annotation to our method:
@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));
}
Next, we’ll go through some of the most used properties within .
3.1. The Property
The required property contains the operation’s summary field. Simply put, it provides a short description of the operation. However, we should keep this parameter shorter than 120 characters.
Here’s how we define the summary property inside the annotation:
@Operation(summary= "Gets customer by ID")
3.2. The Property
Using , we can provide more details about the operation. For instance, we can place a text describing the endpoint’s restrictions:
@Operation(summary= "Gets customer by ID", description= "Customer must exist")
3.3. The Property
The property represents whether or not this operation is hidden.
4.
It’s a common practice to return errors using HTTP status codes. We can use the annotation to describe the concrete possible response of an operation.
While the annotation describes an operation and a general return type, the annotation describes the rest of the possible return codes.
Furthermore, the annotation can be applied at the method level as well as at the class level. Moreover, annotation on the class level will be parsed only if an annotation with the same code is not already defined on the method level. In other words, the method annotations have precedence over class annotations.
We should use the annotations within the annotation whether we have one or multiple responses.
If we use this annotation directly, it will not be parsed by Swagger.Let’s define the and annotations on our method:
@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));
}
We can use the annotation to specify the success response as well:
@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));
}
Now, let’s go through some of the properties used within .
4.1. The and Properties
Both and properties are required parameters in the annotation. It’s important to mention we cannot define more than one with the same code property.
The message property usually contains a human-readable message that goes along with the response:
@ApiResponse(responseCode = 400, message = "Invalid ID supplied")
4.2. The Property
Sometimes, an endpoint uses different response types. For example, we can have one type for success response and another for error response. We can describe them using the optional property by associating a response class as a schema.
Firstly, let’s define a class that will be returned in case of an internal server error:
class ErrorResponse {
private String error;
private String message;
// getters and setters
}
Secondly, let’s add a new for internal server errors:
@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 |
|---|---|
| 用於描述操作 | 用於描述操作的可能響應 |
| 用於成功的響應 | 用於成功響應和錯誤響應 |
| 只能定義在方法級別 | 可以在方法級別或類級別定義 |
| 可以直接使用 | 只能在 標註中使用 |
6. 結論
在本文中,我們學習了 @Operation 和 @ApiResponse 註解之間的區別。