Структура Spring-проекта

  • Рубрика записи:Spring back-end

Так как в идеи Spring Framework входит упрощение типовых задач, то и структура проекта имеет стандартный вид. Вам не нужно изобретать велосипед, когда вы работаете со Spring. В этой статье мы посмотрим, как должна выглядеть структура проекта. В таком её виде она будет помогать, а не мешать разработке. Всё будет на своих местах.

Все папки проекта

Всего в корне SpringBoot-проекта должны иметь место 6 важных папок:

В папке model располагаются классы-сущности, объекты которых представляют собой строки таблиц из базы данных. Класс – таблица, объект этого класса – строка этой таблицы.

Эти объекты вы получаете из БД в своём проекте при помощи классов из папки repository, управляя логикой работы с объектами сущностей с помощью классов из папки service. Классы service имеют в себе классы repository, чтобы выполнять свою работу при помощи них.

Непосредственные http-запросы получают и отвечают на них классы из папки controller. Они пользуются внутри себя классами service.

Папки dto и mapper опциональны, но чаще всего они нужны. Они ответственны за конвертацию объектов сущностей в более простые их варианты.

В проекте могут быть и другие пакеты, классы, но эти – базовые. Дальше мы рассмотрим цель каждой из этих папок и что там хранится.

Сущности

Сущность (Entity) в Spring-разработке – это объект, который отражён в базе данных. Сущностью может быть пользователь User. Это может быть комментарий пользователя Comment или его роль UserRole. Также сущностью может стать заказ Order и предметы OrderItem, которые заказаны в заказе. Да ладно: это может быть всё, что угодно, что вы решите хранить и использовать.

Сущности используются для хранения и манипулирования данными в базе данных с использованием JPA (Java Persistence API) или других подобных технологий. Классы сущностей помечаются аннотацией @Entity и выглядят примерно так:

Сущности в структуре проекта Spring хранятся в папке model. Важный момент: для каждой сущности создаётся свой отдельный репозиторий, свой сервис, свой контроллер и так далее. Например: для сущности User создаются UserRepository, UserService, UserController, UserDto и UserMapper. Бывают исключения, когда напрямую читать, изменять и т.д. сущность в БД не надо.

Для упрощения работы с сущностями, а также с остальными классами, можно использовать библиотеку Lombok. Она позволяет сильно сократить шаблонный код.

Управление сущностями

Недостаточно просто иметь классы-представления таблиц из БД. Нужно их как-то оттуда получать, записывать и удалять, а также проводить более сложные операции.

Слой repository в структуре проекта отвечает за операции, непосредственно связанные с базой данных. Вследствие них происходит чтение, запись, изменение или удаление сущностей, которые представлены объектами. Пример репозитория:

Слой service отвечает за более сложные операции, чем просто управление данными в БД. Однако в простых Spring-приложениях обычно слой service копирует функциональность методов слоя repository. Класс сервиса может выглядеть так:

Взаимодействие с http-запросами

Вот мы и подобрались к http-запросам. Ведь кто-то будет посылать нам просьбы о данных на сервер. А мы должны что-то отвечать. За это ответственен слой controller. Он принимает всяческие get-, post- и другие запросы, а затем посылает на них ответы.

Так как мы пишем чистый back-end без представления данных, мы будем помечать классы контроллеров не аннотацией @Controller, а аннотацией @RestController. В таком случае на запросы будет возвращаться не готовая страничка сайта, а только запрошенные данные. Как эти данные дальше использовать – ответственность запрашивающего.

Пример класса контроллера:

Конвертация сущностей

Конвертация сущностей представляется в Spring-проекте специальными объектами DTO – Data Transfer Object. DTO используются для передачи данных. Они представляют собой упрощённые объекты, которые не обязательно соответствуют структуре базы данных.

Порой слой dto может быть вовсе не нужен, не использован в проекте. Он не такой обязательный, как предыдущие слои. Но, как правило, конвертация сущностей всё-таки нужна. Зачем?

Да потому, что не всегда нужно передавать всю информацию из класса-сущности целиком. Более того, сущности зачастую ссылаются друг на друга. Когда объекты имеют ссылки друг на друга, возникает потенциальная проблема рекурсии при попытке преобразования их в JSON или другой формат для передачи этих объектов или сохранения их в базе данных.

Таким образом, конвертация сущностей отражается в двух папках проекта: dto и mapper. Папка dto содержит непосредственные классы упрощённых сущностей. А папка mapper, в свою очередь, содержит классы, которые умеют конвертировать entity в dto и dto в entity. Можно прописывать эти mapper-ы ручками, однако я предпочитаю использовать библиотеку MapStruct, которая делает это за меня.

Итого, пример dto:

А вот какой пример mapper-а при использовании библиотеки MapStruct:

Это основные принципы структурирования Spring-проекта. Следуя этим шаблонам, вы создадите поддерживаемый, расширяемый и, надеюсь, чистый код. Его смогут понять другие Spring-разработчики, диагонально просмотрев названия папок и файлов в проекте. Вдобавок, вам будет легко найти подходящую информацию в интернетах, так как эта структура – стандартная.

Добавить комментарий