Spring Boot
2026-02-26 20:39 Diff

Типовая задача в веб-разработке — это создание API для CRUD сущности.

CRUD (Create/Read/Update/Delete) — это набор типовых операций, который обычно выполняется над сущностью. В этом уроке мы соберем все изученное и создадим эталонный CRUD на примере поста в блог.

Общий план создания CRUD выглядит так:

  1. Создаем сущность
  2. Создаем репозиторий
  3. Создаем DTO
  4. Создаем маппер
  5. Пишем тест
  6. Реализуем контроллер

Создание сущности

У поста в блоге есть четыре основных свойства:

  • Название
  • Слаг
  • Текст
  • Автор

Кроме того, еще можно добавить дату создания и последнего обновления:

Создание репозитория

Использование слага в URL-адресе подразумевает, что мы сможем делать выборку сущности по слагу:

Сразу добавим этот метод в репозиторий:

Создание DTO

В целом нам понадобятся три разных DTO — для создания, обновления и просмотра поста:

Создание маппера

Для CRUD нам нужны три операции:

  • Конвертация DTO для создания в пост
  • Конвертация поста в DTO для просмотра
  • Обновление поста на основе DTO для обновления

Самое интересное в этом коде — это конвертация authorId из DTO в свойство author внутри поста. Чтобы выполнить эту операцию, нужно сделать запрос в базу данных и извлечь объект автора. По умолчанию MapStruct такого не умеет, но для него можно создать маппер, который решает эту задачу. Здесь мы сразу приведем его код:

Чтобы этот код заработал, необходимо внедрить общий базовый интерфейс для всех моделей, на который маппер мог бы ориентироваться и понимать, применять метод toEntity(). Мы назовем его BaseEntity:

Определение класса Post в таком случае выглядит так:

Создание теста

Код интеграционных тестов не завязан на устройство контроллера. Поэтому сам тест можно написать до реализации контроллера — так мы упростим создание контроллера и проверку его работоспособности. Такой подход называется TDD (Test Driven Development):

Реализация контроллера

Перейдем к контроллеру. Здесь мы не добавляем ничего нового. Весь его код мы видели частями, а теперь собираем все вместе:

В целом, CRUD не ограничивается только перечисленными методами. По ситуации методов может быть больше:

  • Если у нас есть какое-то особое обновление и вывод списка
  • Если у нас есть несколько контроллеров для одной и той же сущности (например, для управления постами для пользователей и для администраторов нужно два разных контроллера)