8.8 KiB
Архитектура и структура сервиса
Документ описывает как организован сервер дипломного проекта: какие слои присутствуют, как они взаимодействуют и где искать ключевые модули.
Общий обзор
Сервис написан на Kotlin с использованием Ktor и разворачивается как Netty-приложение (Application.kt). Приложение поднимает инфраструктурные плагины (HTTP, сериализация, безопасность) и регистрирует доменные маршруты. Все функции сгруппированы в повторяющийся паттерн Controller → Service → Repository → Entity, что делает поддержку CRUD-операций симметричной во всех доменных областях.
Высокоуровневый поток запросов:
- HTTP-вызов попадает в
Routing.kt, где маршруты разделены на публичную и админскую зоны (/api/v1/...). - Контроллер модуля занимается десериализацией запроса, базовой валидацией и формированием ответа.
- Сервис инкапсулирует бизнес-правила: публикация материалов, фильтрация, проверка прав, подготовка DTO.
- Репозиторий обращается к PostgreSQL через Ktorm, используя HikariCP-пул соединений.
- Исключения (
ValidationException,NotFoundException) перехватываетStatusPages, что обеспечивает единый контракт ошибок.
Графическая схема слоев расположена в docs/crud-model.svg.
Структура каталогов
src/main/kotlin
├── app # Bootstrap: Application, Routing, Security, HTTP, Database
├── shared # Переиспользуемые DTO, пагинация, ошибки
└── modules # Доменные модули (admin, news, service, serviceCategory, lead)
src/main/resources
├── application.yaml # Конфигурация Ktor
└── openapi # Спецификации API
src/test/kotlin # Зеркало production-пакетов для тестов
docs/
├── crud-model.svg # Диаграмма последовательности CRUD
└── architecture.md # Текущий документ
Инфраструктурный слой (app/*)
- Application.module – точка входа, выстраивает последовательность
configureDatabase → configureHTTP → configureSerialization → configureSecurity → configureRouting. - Database.kt – инициализация пула HikariCP (настройки берутся из
.env), регистрацияDatabaseвApplication.attributes. - Http.kt – подключает плагины Ktor (CORS, Compression, CachingHeaders, StatusPages, Swagger UI). Здесь же централизованно обрабатываются исключения.
- Serialization.kt –
ContentNegotiationсkotlinx.serialization. - Security.kt – загрузка параметров JWT из окружения, настройка схемы
admin-auth, валидацияJWTPrincipal. - Routing.kt – собирает зависимости модулей, подключает публичные маршруты и оборачивает админские роуты в
authenticate("admin-auth").
Доменные модули (modules/*)
Каждый модуль состоит из четырех файлов:
Controller.kt– набор Ktor-маршрутов для публичной и/или админской зоны.Service.kt– бизнес-логика. Например,NewsServiceотвечает за публикацию, пагинацию и преобразование сущностей в DTO, аServiceServiceподдерживает фильтры по статусу, категории и ценовому диапазону.Repository.kt– слой доступа к данным на Ktorm: построение SQL, пагинация, CRUD-операции, трансформации вEntity.Entity.kt/ DTO – описания таблиц, модели для сериализации и транспортировки данных.
Admin
Отвечает за регистрацию, авторизацию и управление администраторами. Использует BcryptPasswordHasher для хранения паролей и TokenService для выпуска JWT. Публичная часть (/admin/login) возвращает токен; защищенная (/admin/*) требует admin-auth.
News
Два набора маршрутов: публичные (/news, /news/{slug}) и админские (/admin/news). Сервис применяет правила публикации и формирует страницы (Page<T>). Репозиторий обрабатывает SQL для списков и выборок по slug.
Services и Service Categories
ServiceController поддерживает сложные фильтры (категория, диапазон цен, статус). ServiceService связывает услуги с категориями, обеспечивая получение вложенных DTO. ServiceCategory* модули обслуживают справочник категорий и проверяют уникальность slug.
Leads
publicLeadRoutes принимает заявки с сайта (POST /leads), adminLeadRoutes предоставляет CRUD для операторов. Сервис выполняет базовую валидацию и поиск по строке q.
Общие компоненты (shared/*)
shared.pagination.Page– универсальный ответ для списков.shared.errors.ValidationException/NotFoundException– типы, которые перехватываютсяStatusPagesи автоматически конвертируются в HTTP-ответ.
Работа с БД
- База – PostgreSQL, подключение через Ktorm + HikariCP (
jdbc:postgresql://...). - Пулы – настраиваются через переменные окружения (
DB_HOST,DB_POOL_MAXи т.д.). - Репозитории – реализованы вручную на SQL Builder, что дает контроль над запросами и связями между таблицами (
services↔service_categories,news,leads,admins).
Безопасность
- Единственная схемa аутентификации – JWT
admin-auth. - Конфигурация (
JWT_SECRET,JWT_ISSUER,JWT_AUDIENCE,JWT_EXPIRES_MIN) читается из.envили переменных окружения. - Public маршруты доступны без токена, все
admin*Routesподключены внутриauthenticate.
Сборка и эксплуатация
- Основные команды Gradle:
./gradlew run– локальный сервер../gradlew test– прогон тестов (обязателен перед пушем)../gradlew buildFatJar– сборка standalone JAR../gradlew buildImage/runDocker– сборка и запуск docker-образа.
- Конфигурация HTTP-порта, логирования и OpenAPI лежит в
src/main/resources/application.yamlиresources/openapi. - Для обновления документации добавляйте артефакты в
docs/(например, текущую архитектурную схему и диаграмму CRUD).
Тестирование
Тесты зеркалируют production-пакеты (src/test/kotlin/...). При добавлении новой функциональности рекомендуется:
- Класть тесты в соответствующий пакет модуля (например,
modules/news/NewsServiceTest.kt). - Проверять ветки успеха, валидации и авторизации.
- Запускать
./gradlew testперед коммитом, чтобы убедиться в корректной работе всего набора.