В предыдущих лекциях мы изучили основы 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-страницы для наших веб-приложений.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ