Hướng dẫn sử dụng Spring Boot 2.7.5 để xây dựng API RESTful

Spring MVC và xử lý yêu cầu HTTP

Định nghĩa endpoint

Sử dụng @RestController để tự động trả về dữ liệu JSON, tương đương với @Controller + @ResponseBody.

Ánh xạ URL bằng @RequestMapping hoặc các biến thể cụ thể như @GetMapping, @PostMapping để ràng buộc phương thức HTTP.

Nhận tham số từ client

  • Không dùng annotation: Spring tự động bind tham số từ query string vào đối tượng.
    @GetMapping("/user")
    public Person getUser(Person person) {
        return person;
    }
    Gọi: /user?name=Nguyễn Văn A&age=25
  • @RequestParam: Ràng buộc tham số từ query string.
    @GetMapping("/info")
    public Person getInfo(@RequestParam String name, @RequestParam int age) {
        return new Person(name, age);
    }
  • @PathVariable: Lấy giá trị từ đường dẫn URL.
    @GetMapping("/profile/{username}/{years}")
    public Person getProfile(@PathVariable String username, @PathVariable int years) {
        return new Person(username, years);
    }
    Gọi: /profile/Nguyễn Văn A/25
  • @RequestBody: Nhận dữ liệu JSON từ body request.
    @PostMapping("/register")
    public Person register(@RequestBody Person person) {
        return person;
    }
    Body request (Content-Type: application/json):
    {
      "name": "Nguyễn Văn A",
      "age": 25
    }

Xác thực dữ liệu đầu vào

Thêm dependency spring-boot-starter-validation và sử dụng các annotation như @NotBlank, @Min trên field entity.

public class Person {
    @NotBlank(message = "Tên không được để trống")
    private String name;

    @Min(value = 1, message = "Tuổi phải lớn hơn 0")
    private int age;
}

Trong controller, thêm @Valid trước tham số cần validate:

@PostMapping("/validate")
public Person validatePerson(@RequestBody @Valid Person person) {
    return person;
}

Interceptor - Xử lý trước/sau controller

Tạo interceptor để can thiệp vào luồng xử lý request:

@Component
public class RequestInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
        System.out.println("Trước khi xử lý controller");
        return true; // tiếp tục xử lý
    }

    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView mv) {
        System.out.println("Sau khi controller xử lý xong");
    }

    @Override
    public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex) {
        System.out.println("Hoàn tất request");
    }
}

Đăng ký interceptor trong cấu hình:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private RequestInterceptor interceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor);
    }
}

Thiết kế API theo chuẩn RESTful

Tích hợp Swagger UI

Thêm dependency springfox-boot-starter và cấu hình:

@Configuration
@EnableOpenApi
public class SwaggerConfig {
    @Bean
    public Docket apiDoc() {
        return new Docket(DocumentationType.OAS_30)
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(new ApiInfoBuilder()
                    .title("Tài liệu API")
                    .version("1.0")
                    .build());
    }
}

Gắn annotation cho controller:

@RestController
@Api(tags = "Quản lý người dùng")
public class UserController {
    @GetMapping("/users/{id}")
    @ApiOperation("Lấy thông tin người dùng theo ID")
    public Person findUser(@PathVariable String id) {
        return new Person(id, 30);
    }
}

Truy cập tài liệu tại: /swagger-ui/index.html

Thay thế bằng Knife4j

Sử dụng knife4j-spring-boot-starter để có giao diện đẹp hơn, không cần thay đổi code. Truy cập tại: /doc.html

Ví dụ thực tế RESTful

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{username}")
    public Person fetchUser(@PathVariable String username) {
        return new Person(username, 25);
    }

    @PostMapping
    public boolean addUser(@RequestBody Person user) {
        return user != null;
    }

    @PutMapping
    public boolean modifyUser(@RequestBody Person user) {
        return user != null;
    }

    @DeleteMapping("/{username}")
    public boolean removeUser(@PathVariable String username) {
        return username != null;
    }
}

Lưu trữ dữ liệu và các kỹ thuật hỗ trợ

Các phần về kết nối cơ sở dữ liệu, kiểm thử đơn vị, xử lý ngoại lệ và ghi log sẽ được trình bày chi tiết trong các bài hướng dẫn tiếp theo.

Thẻ: spring-boot spring-mvc restful-api Swagger knife4j

Đăng vào ngày 12 tháng 6 lúc 21:14