Какие слои есть в веб-приложении начиная с контроллера
Что проверяют
Понимаете ли вы, зачем вообще нужны слои, что каждый из них делает в Spring-приложении и чего делать не должен. Следом почти всегда спрашивают, где у вас стоит @Transactional и почему не на контроллере.
Как отвечать
Классическая схема для Spring Boot сверху вниз:
- контроллер (
@RestController): принимает HTTP-запрос, валидирует вход через@Validи Bean Validation, превращает DTO в вызов сервиса и выбирает код ответа. Бизнес-логики тут нет, ошибки централизованно обрабатывает@RestControllerAdvice; - сервис (
@Service): бизнес-правила и сценарии. Здесь же граница транзакции через@Transactional: одна операция пользователя это одна транзакция, даже если она трогает несколько репозиториев; - репозиторий (
@Repository, обычноJpaRepositoryиз Spring Data): доступ к данным и запросы, без логики. Исключения драйвера Spring переводит в иерархиюDataAccessException; - доменная модель: сущности
@Entityи отдельно DTO для входа и выхода API. Преобразование ручное или через MapStruct; - интеграции: клиенты внешних сервисов (
RestClient,WebClient), отправка сообщений в брокер. Их выносят отдельно, чтобы сервис не знал про HTTP и сериализацию.
Добавьте, что до контроллера запрос проходит фильтры (включая цепочку Spring Security), DispatcherServlet, интерсепторы и конвертеры сообщений, где Jackson превращает JSON в объект.
Смысл слоёв лучше всего виден на тестах: контроллер проверяют через @WebMvcTest с замоканным сервисом, репозиторий через @DataJpaTest, сервис обычным юнит-тестом с Mockito. Из альтернатив стоит знать гексагональную архитектуру и деление пакетов по фичам.
Где спотыкаются
Отдают @Entity прямо из контроллера. Ленивые связи ловят LazyInitializationException или тянут полбазы при сериализации, а включённый по умолчанию spring.jpa.open-in-view только маскирует проблему лишними запросами.
Вешают @Transactional на приватный метод или вызывают транзакционный метод из того же класса. Вызов идёт мимо прокси, и транзакция не открывается.
Называют View обязательным слоем REST-сервиса. В JSON API шаблонизатора нет, эту роль играют DTO и сериализация.