Trong bài viết trước, mình đã hướng dẫn các bạn cách sử dụng thư viện Springfox để tạo RESTful API documentation theo OpenAPI specification trong các ứng dụng Spring Boot. Thế nhưng Springfox thì đã lâu rồi không còn cập nhập còn thư viện springdoc-openapi thì được cập nhập liên tục và có chức năng giống như Springfox nên các bạn nên sử dụng thư viện springdoc-openapi từ giờ trở đi các bạn nhé. Trong bài viết này, mình sẽ hướng dẫn các bạn cách tạo RESTful API documentation với thư viện springdoc-openapi trong ứng dụng Spring Boot.
Đầu tiên, mình sẽ tạo mới Spring Boot project với Spring Web dependency để làm ví dụ.
Kết quả như sau:
Mình sẽ thêm Springdoc OpenAPI Starter WebMVC UI dependency như sau:
1 2 3 4 5 |
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.1.0</version> </dependency> |
Nếu các bạn đang sử dụng Spring WebFlux thì hãy thêm dependency sau dành cho nó nhé:
1 2 3 4 5 |
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webflux-ui</artifactId> <version>2.1.0</version> </dependency> |
Giả sử bây giờ mình cũng có một controller định nghĩa một API để quản lý thông tin sinh viên đơn giản như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdanjava.springboot; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value = "/student") public class StudentController { @GetMapping(value = "findById") public String findById(int id) { return "Khanh"; } } |
Nếu bây giờ các bạn chạy ứng dụng Spring Boot này lên rồi truy cập tới địa chỉ http://localhost:8080/swagger-ui/index.html, các bạn sẽ thấy kết quả tương tự như khi chúng ta sử dụng Springfox như sau:
Mặc định thì Springdoc-openapi cũng sẽ scan hết tất cả các controller có trong ứng dụng của chúng ta để generate document cho những API được định nghĩa.
Tương tự như class Docket trong Springfox, Springdoc-openapi định nghĩa class GroupedOpenApi giúp chúng ta cấu hình các thông tin để generate API documentation, ví dụ như sau:
1 2 3 4 5 6 7 8 |
@Bean GroupedOpenApi studentApi() { return GroupedOpenApi.builder() .group("Huong Dan Java") .packagesToScan("com.huongdanjava.springboot") .pathsToMatch("/student/*") .build(); } |
Thông tin group là thông tin bắt buộc các bạn cần phải khai báo khi định nghĩa bean sử dụng class GroupedOpenApi. Tương tự như Springfox thì Springdoc-openapi cũng cho phép chúng ta scan các API filter theo package hoặc theo context path.
Kết quả, các bạn sẽ thấy phần group sẽ được hiển thị trong field “Select a definition” như sau:
Các bạn có thể sử dụng các class Customizers nằm trong package org.springdoc.core.customizers của Springdoc-openapi để custom API documentation theo cách mình muốn.
Ví dụ, mình muốn thay đổi title được hiển thị cho group “Huong Dan Java” của mình ở trên từ “OpenAPI definition” thành “Student API”, mình sẽ thêm OpenApiCustomizer như sau:
1 2 3 4 5 6 7 8 9 |
@Bean GroupedOpenApi studentApi() { return GroupedOpenApi.builder() .group("Huong Dan Java") .packagesToScan("com.huongdanjava.springboot") .pathsToMatch("/student/*") .addOpenApiCustomizer(openApi -> openApi.info(new Info().title("Student API"))) .build(); } |
Kết quả:
Chúng ta cũng có thể customize document cho các API bằng cách thêm một số description về nó, các dữ liệu trả về, tương tự như Springfox.
Ví dụ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.huongdanjava.springboot; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @RestController @RequestMapping(value = "/student") public class StudentController { @GetMapping(value = "findById") @Operation(summary = "Find student by id") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "422", description = "Student not found"), @ApiResponse(responseCode = "417", description = "Exception failed") }) public String findById(int id) { return "Khanh"; } } |
Kết quả cũng tương tự như khi chúng ta sử dụng Springfox các bạn nhé: