Xây dựng API RESTful với Spring Boot @RestController
Chào mừng bạn đến với bài viết thứ 4 trong series về Spring và Spring Boot. Ở bài viết này, chúng ta sẽ khám phá cách xây dựng API RESTful mạnh mẽ sử dụng Spring Boot và annotation @RestController. Chúng ta sẽ đi sâu vào các nguyên tắc REST, cách tạo các endpoint CRUD (Create, Read, Update, Delete), và cách sử dụng các annotation quan trọng như @GetMapping, @PostMapping, @PutMapping, và @DeleteMapping.
Các Nguyên Tắc Cơ Bản của REST
REST (Representational State Transfer) là một kiến trúc phần mềm để xây dựng các ứng dụng web. Nó dựa trên một số nguyên tắc chính:
- Client-Server: Client và server hoạt động độc lập.
- Stateless: Server không lưu trữ trạng thái của client giữa các request.
- Cacheable: Responses từ server có thể được cache để cải thiện hiệu suất.
- Layered System: Client không cần biết về tất cả các lớp trung gian giữa nó và server.
- Uniform Interface: REST định nghĩa một giao diện thống nhất giữa client và server. Giao diện này bao gồm các phương thức HTTP (GET, POST, PUT, DELETE), tài nguyên (resources) được xác định bằng URI, và định dạng dữ liệu (JSON, XML).
Việc tuân thủ các nguyên tắc này giúp API của bạn trở nên dễ mở rộng, dễ bảo trì và tương tác.
Xây dựng API với @RestController
@RestController là một annotation trong Spring Boot. Nó kết hợp @Controller và @ResponseBody. @Controller đánh dấu một class là một controller. @ResponseBody cho biết rằng kết quả trả về từ các method trong controller nên được ghi trực tiếp vào body của response HTTP. Điều này rất hữu ích khi xây dựng API RESTful, nơi chúng ta thường trả về dữ liệu JSON hoặc XML.
Để sử dụng @RestController, bạn chỉ cần đánh dấu class của bạn bằng annotation này:
@RestController
public class MyController {
// Các endpoint của bạn ở đây
}
Xây dựng Endpoint CRUD
CRUD là viết tắt của Create, Read, Update, và Delete. Đây là các hoạt động cơ bản mà chúng ta thường thực hiện trên dữ liệu. Với Spring Boot, chúng ta có thể dễ dàng xây dựng các endpoint CRUD bằng cách sử dụng các annotation như @GetMapping, @PostMapping, @PutMapping, và @DeleteMapping.
@PostMapping: Tạo mới (Create)
@PostMapping được sử dụng để xử lý các request POST. Thường dùng để tạo mới một resource.
@PostMapping("/products")
public ResponseEntity<Product> createProduct(@RequestBody Product product) {
// Lưu sản phẩm vào database
Product savedProduct = productService.save(product);
return new ResponseEntity<>(savedProduct, HttpStatus.CREATED);
}
Trong ví dụ này, @RequestBody cho phép chúng ta nhận dữ liệu từ body của request và chuyển đổi nó thành một đối tượng Product. ResponseEntity cho phép chúng ta kiểm soát status code và body của response.
@GetMapping: Đọc (Read)
@GetMapping được sử dụng để xử lý các request GET. Thường dùng để lấy thông tin về một hoặc nhiều resource.
@GetMapping("/products/{id}")
public ResponseEntity<Product> getProduct(@PathVariable Long id) {
// Lấy sản phẩm từ database theo ID
Optional<Product> product = productService.findById(id);
if (product.isPresent()) {
return new ResponseEntity<>(product.get(), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@GetMapping("/products")
public ResponseEntity<List<Product>> getAllProducts() {
// Lấy tất cả sản phẩm từ database
List<Product> products = productService.findAll();
return new ResponseEntity<>(products, HttpStatus.OK);
}
Ở đây, @PathVariable cho phép chúng ta trích xuất giá trị từ URL. Ví dụ: nếu URL là /products/123, thì giá trị của id sẽ là 123.
@PutMapping: Cập nhật (Update)
@PutMapping được sử dụng để xử lý các request PUT. Thường dùng để cập nhật một resource hiện có.
@PutMapping("/products/{id}")
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product product) {
// Kiểm tra xem sản phẩm có tồn tại không
Optional<Product> existingProduct = productService.findById(id);
if (existingProduct.isPresent()) {
product.setId(id);
Product updatedProduct = productService.save(product);
return new ResponseEntity<>(updatedProduct, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
Tương tự như @PostMapping, chúng ta sử dụng @RequestBody để nhận dữ liệu từ body của request.
@DeleteMapping: Xóa (Delete)
@DeleteMapping được sử dụng để xử lý các request DELETE. Thường dùng để xóa một resource.
@DeleteMapping("/products/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
// Kiểm tra xem sản phẩm có tồn tại không
Optional<Product> product = productService.findById(id);
if (product.isPresent()) {
productService.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
Trong trường hợp xóa thành công, chúng ta thường trả về status code 204 (NO_CONTENT).
Xử lý Path Variables (@PathVariable) và Request Parameters (@RequestParam)
Chúng ta đã thấy cách sử dụng @PathVariable để trích xuất giá trị từ URL. Ngoài ra, chúng ta còn có thể sử dụng @RequestParam để trích xuất giá trị từ query parameters.
Ví dụ:
@GetMapping("/products")
public ResponseEntity<List<Product>> getProductsByName(@RequestParam(value = "name", required = false) String name) {
if (name != null) {
// Tìm kiếm sản phẩm theo tên
List<Product> products = productService.findByName(name);
return new ResponseEntity<>(products, HttpStatus.OK);
} else {
// Trả về tất cả sản phẩm
List<Product> products = productService.findAll();
return new ResponseEntity<>(products, HttpStatus.OK);
}
}
Trong ví dụ này, nếu URL là /products?name=example, thì giá trị của name sẽ là "example". Thuộc tính required = false cho biết rằng parameter này là không bắt buộc.
Sử dụng ResponseEntity để Kiểm Soát HTTP Status Code
ResponseEntity là một class trong Spring. Nó cho phép chúng ta kiểm soát hoàn toàn response HTTP, bao gồm status code, headers, và body. Chúng ta đã thấy cách sử dụng ResponseEntity trong các ví dụ trước. Việc sử dụng ResponseEntity giúp bạn xây dựng các API tuân thủ chặt chẽ các tiêu chuẩn HTTP.
Ví dụ, bạn có thể trả về status code 201 (CREATED) khi tạo mới một resource, hoặc status code 404 (NOT_FOUND) nếu resource không tồn tại.
Ví dụ Hoàn Chỉnh
Dưới đây là một ví dụ hoàn chỉnh về một controller RESTful với các endpoint CRUD cho tài nguyên "Product":
@RestController
@RequestMapping("/api")
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping("/products")
public ResponseEntity<Product> createProduct(@RequestBody Product product) {
Product savedProduct = productService.save(product);
return new ResponseEntity<>(savedProduct, HttpStatus.CREATED);
}
@GetMapping("/products/{id}")
public ResponseEntity<Product> getProduct(@PathVariable Long id) {
Optional<Product> product = productService.findById(id);
if (product.isPresent()) {
return new ResponseEntity<>(product.get(), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@GetMapping("/products")
public ResponseEntity<List<Product>> getAllProducts() {
List<Product> products = productService.findAll();
return new ResponseEntity<>(products, HttpStatus.OK);
}
@PutMapping("/products/{id}")
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product product) {
Optional<Product> existingProduct = productService.findById(id);
if (existingProduct.isPresent()) {
product.setId(id);
Product updatedProduct = productService.save(product);
return new ResponseEntity<>(updatedProduct, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@DeleteMapping("/products/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
Optional<Product> product = productService.findById(id);
if (product.isPresent()) {
productService.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
}
Kết luận
Trong bài viết này, chúng ta đã tìm hiểu cách xây dựng API RESTful sử dụng Spring Boot và @RestController. Chúng ta đã đi qua các nguyên tắc cơ bản của REST, cách tạo các endpoint CRUD, cách sử dụng @GetMapping, @PostMapping, @PutMapping, và @DeleteMapping, cách xử lý Path Variables và Request Parameters, và cách sử dụng ResponseEntity để kiểm soát HTTP status code. Hy vọng rằng bài viết này sẽ giúp bạn xây dựng các API RESTful mạnh mẽ và dễ bảo trì. Hãy tiếp tục khám phá các tính năng khác của Spring Boot để nâng cao kỹ năng phát triển ứng dụng web của bạn!
0 Bình luận
Vui lòng đăng nhập để gửi bình luận.