У попередніх лекціях ми розібрали основи Spring MVC: архітектуру, ключові анотації й базові принципи маршрутизації. Тепер пора застосувати ці знання на практиці і створити повноцінний REST API.
Давайте розробимо контролер для керування книгами в бібліотеці. Наш API вмітиме отримувати список книг, знаходити книгу за ID, додавати нові книги, оновлювати інформацію про них і видаляти їх з бази. У процесі ми створимо всі необхідні CRUD-операції, навчимося правильно обробляти HTTP-методи (GET, POST, PUT, DELETE), налаштуємо повернення даних у форматі JSON і додамо базове тестування.
REST API — це фундамент сучасної веб-розробки. Незалежно від того, розробляєте ви веб-додаток, мобільний додаток чи мікросервісну архітектуру, вам доведеться створювати і підтримувати API-endpoints. Давайте навчимося робити це правильно!
1. Підготовка проєкту
Залежності. Спочатку переконаємось, що наш Spring Boot проєкт налаштований правильно. Додамо в проєкт потрібні залежності у файлі pom.xml:
<dependencies>
<!-- Spring Web для роботи з MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Залежність для роботи з JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
А тепер переходимо до створення контролера.
2. Опис сутності Book
Перш ніж братись за реалізацію контролера, нам потрібна сутність, яку він буде обробляти. Створимо простий клас для сутності Book.
package com.example.demo.model;
public class Book {
private Long id;
private String title;
private String author;
// Конструктори
public Book() {}
public Book(Long id, String title, String author) {
this.id = id;
this.title = title;
this.author = author;
}
// Геттери і сеттери
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
3. Створення REST-контролера
Тепер ми готові взятись за створення контролера. Він буде обробляти HTTP-запити для керування книгами. Використаємо анотацію @RestController, щоб сказати Spring, що цей клас відповідає за обробку REST-запитів.
package com.example.demo.controller;
import com.example.demo.model.Book;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
private final List<Book> books = new ArrayList<>();
// Ініціалізація даних
public BookController() {
books.add(new Book(1L, "Clean Code", "Robert C. Martin"));
books.add(new Book(2L, "Effective Java", "Joshua Bloch"));
}
// Отримання всіх книг
@GetMapping
public List<Book> getAllBooks() {
return books;
}
// Отримання книги за ID
@GetMapping("/{id}")
public Book getBookById(@PathVariable Long id) {
return books.stream()
.filter(book -> book.getId().equals(id))
.findFirst()
.orElseThrow(() -> new RuntimeException("Book not found"));
}
// Створення нової книги
@PostMapping
public Book createBook(@RequestBody Book book) {
books.add(book);
return book;
}
// Оновлення книги
@PutMapping("/{id}")
public Book updateBook(@PathVariable Long id, @RequestBody Book updatedBook) {
Book book = getBookById(id);
book.setTitle(updatedBook.getTitle());
book.setAuthor(updatedBook.getAuthor());
return book;
}
// Видалення книги
@DeleteMapping("/{id}")
public void deleteBook(@PathVariable Long id) {
Book book = getBookById(id);
books.remove(book);
}
}
4. Розбір коду контролера
Основні методи контролера
- GET
/booksПовертає список усіх книг. Дуже просто, використовує полеbooksдля повернення списку. - GET
/books/{id}Знаходить книгу за ID. Якщо книгу не знайдено, кидається виключення (можна покращити обробку помилок, але про це пізніше). - POST
/booksСтворює нову книгу. Ми передаємо об'єктBookв тілі запиту (анотація@RequestBody). - PUT
/books/{id}Оновлює існуючу книгу за ID. Спочатку знаходимо книгу за ID, а потім оновлюємо її дані. - DELETE
/books/{id}Видаляє книгу за ID. Спочатку шукаємо книгу, потім видаляємо зі списку.
Параметри анотацій
@RequestMapping("/books"): базовий шлях для всіх запитів.@GetMapping,@PostMapping,@PutMapping,@DeleteMapping: обробка HTTP-запитів.@PathVariableизвлекає параметри з шляху запиту.@RequestBodyчитає тіло запиту і перетворює його в Java-об'єкт.
5. Тестування контролера
Перевірити роботу API можна за допомогою інструментів на кшталт Postman або звичайного cURL. Приклади запитів:
GET всі книги
GET http://localhost:8080/books
GET книга за ID
GET http://localhost:8080/books
POST нова книга
POST http://localhost:8080/books
Content-Type: application/json
{
"id": 3,
"title": "The Pragmatic Programmer",
"author": "Andrew Hunt"
}
DELETE видалення книги
DELETE http://localhost:8080/books/1
6. Типові помилки та їх усунення
- Помилка
404 Not FoundприGET /books/{id}Це відбувається, якщо шуканої книги немає в списку. Переконайтесь, щоbooksініціалізований правильно. - Помилка в серіалізації JSON Перевірте, що всі поля об'єктів мають геттери/сеттери, інакше Jackson не зможе перетворити об'єкт у JSON.
- Помилка
415 Unsupported Media TypeприPOSTабоPUTзапитах Переконайтесь, що заголовок запиту міститьContent-Type: application/json.
Тепер у нас є повністю функціональний REST-контролер! У наступній лекції познайомимось з шаблонізатором Thymeleaf, щоб навчитися створювати гарні HTML-сторінки для наших веб-застосунків.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ