[SB24] RESTful API Document Tạo với Spring Boot + Swagger
- Giới thiệu
- cài đặt
- Tổng quan Swagger
- Prepare
- Config Swagger
- Góc custom
Giới thiệu
Spring Boot hỗ trợ chúng ta tạo ra RESTful API một cách nhanh chóng và tiện lợi, giúp sản phẩm được vận hành nhanh nhất có thể.
Tuy nhiên, Việc deploy nhanh chóng một services không đồng nghĩa với việc nó có thể sử dụng được. Thông thường, tất cả các API sau khi được đưa lên sẽ phải đi kèm với document mô tả, để bất kì ai sử dụng đến thì có thể tra cứu.
Thật không may là việc làm document chưa bao giờ là dễ dàng cả :(( từ lí do này, Swagger
ra đời để giúp chúng ta mô tả tài liệu dự án một cách nhanh chóng bằng annotation.
Trong bài có đề cập các kiến thức:
- Spring Boot
- jpa
- lombok
cài đặt
Trong bài này, tôi sẽ hướng dẫn các bạn sử dụng Swagger2
và tuân theo các quy tắc cảu Swagger Specification 2.0 nhé.
Tại thời điểm viết bài này, hiện phiên bản mới nhất là 3, tuy nhiên, nó sẽ là OpenAPI 3.0.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.5.RELEASE</version><relativePath/> <!-- lookup parent from repository -->
</parent><groupId>me.loda.spring</groupId><artifactId>example-independent-maven-spring-project</artifactId><version>0.0.1-SNAPSHOT</version><name>example-independent-maven-spring-project</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><!--spring jpa-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--in memory database-->
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
springfox
là một thư viện java implementation của Swagger Specification.
springfox-swagger2
chứa core của swagger, giúp chúng ta khai báo document cho api.
springfox-swagger-ui
giúp chúng ta biểu diễn tài liệu dưới dạng web view, dễ nhìn và test.
Tổng quan Swagger
Để sử dụng cơ bản thì Swagger
cung cấp một số các Annotations hữu ích sau:
Chúng ta đi vào thực hành thử nhé.
Đại loại sau khi làm xong, chúng ta sẽ có 1 web view document như thế này:
!image
Prepare
Tạo ra class Model
User.java
@Data
@Entity
@Table
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String email;
}
UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
Khi đã có được Model và Repository, chúng ta sẽ tạo Controller để thao tác liên quan tới User
nhé.
@RestController
@RequestMapping("/api/v1")
@RequiredArgsConstructor
public class UserController {
private final UserRepository userRepository;
@GetMapping("/users")
public List<User> getAllUsers() {
return userRepository.findAll();
}
@GetMapping("/users/{id}")
public User getUser(@PathVariable("id") Long id) {
return userRepository.findById(id).orElse(new User());
}
@PostMapping("/users")
public User createUser(@Valid @RequestBody User user) {
return userRepository.save(user);
}
@PutMapping("/users/{id}")
public User updateUser(@PathVariable("id") Long id, @Valid @RequestBody User user) {
user.setId(id);
return userRepository.save(user);
}
@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable("id") Long id) {
userRepository.deleteById(id);
}
}
Âu khê, tạm thời như thế đã 😂
Bây giờ vào phần chính, config Swagger
cho dự án của chúng ta.
Config Swagger
Thật may mắn, trước khi đi vào các custom phức tạp thì Swagger hỗ trợ chúng ta tự động sinh ra tài liệu một cách mặc định mà chưa cần phải khai báo bất kì annotation nào đã giới thiệu ở trên.
Chỉ cần tạo ra đối tượng Docket
của Swagger
và nó sẽ quét hết các địa chỉ API mà bạn chỉ định, rồi tự động sinh ra tài liệu cơ bản cho chúng ta.
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("me.loda.spring.swagger.controller"))
.paths(PathSelectors.regex("/.*"))
.build()
.apiInfo(apiEndPointsInfo());
}
private ApiInfo apiEndPointsInfo() {
return new ApiInfoBuilder().title("Spring Boot REST API")
.description("Employee Management REST API")
.contact(new Contact("loda", "https://loda.me/", "loda.namnh@gmail.com"))
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.version("1.0.0")
.build();
}
}
Các thứ cần lưu ý bao gồm:
- Để
Swagger
hoạt động, bạn nhớ kích hoạt nó bằng@EnableSwagger2
. - Bạn có thể chọn nơi chứa các API bằng
RequestHandlerSelectors
. Nếu muốn quét hết cả project, có thể xàiRequestHandlerSelectors.any()
- Bạn có thể chỉ định bộ lọc cho các api bằng
PathSelectors
. Nếu muốn quét tất cả, chọnPathSelectors.any()
.
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Bây giờ, chạy thử và vào địa chỉ http://localhost:8080/swagger-ui.html
để xem thành quả nhé.
Góc custom
Bạn có thể chỉ định rõ hơn các mô tả của tài liệu bằng cách sử dụng các Annotation mà Swagger
cung cấp.
User.java
@Data
@Entity
@Table
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "User model")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(notes = "The database generated User ID")
private Long id;
private String firstName;
private String lastName;
private String email;
}
UserController.java
@RestController
@RequestMapping("/api/v1")
@RequiredArgsConstructor
@Api(value = "User APIs")
public class UserController {
private final UserRepository userRepository;
@ApiOperation(value = "Xem danh sách User", response = List.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Thành công"),
@ApiResponse(code = 401, message = "Chưa xác thực"),
@ApiResponse(code = 403, message = "Truy cập bị cấm"),
@ApiResponse(code = 404, message = "Không tìm thấy")
})
@GetMapping("/users")
public List<User> getAllUsers() {
return userRepository.findAll();
}
@GetMapping("/users/{id}")
public User getUser(@PathVariable("id") Long id) {
return userRepository.findById(id).orElse(new User());
}
@PostMapping("/users")
public User createUser(
@ApiParam(value = "Đối tượng User cần tạo mới", required = true) @Valid @RequestBody User user
) {
return userRepository.save(user);
}
@PutMapping("/users/{id}")
public User updateUser(@PathVariable("id") Long id, @Valid @RequestBody User user) {
user.setId(id);
return userRepository.save(user);
}
@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable("id") Long id) {
userRepository.deleteById(id);
}
}
Tới đây bạn có thể sử dụng Swagger thoải mái rồi, tôi sẽ làm một bài khác về OpenAPI 3.0.
💁 Nếu có, toàn bộ project / code mẫu được lưu trữ tại GitHub
🌟 Đây là một bài viết trong Series Làm chủ Spring Boot – Zero to Hero