Автор статьи: Сергей Прощаев (@sproshchaev)
Руководитель направления Java-разработки в FinTech и преподаватель курса Kotlin Backend Developer. Professional в Otus
Всем привет, меня зовут Сергей Прощаев, и в этой статье я расскажу про то, с чего на самом деле стоит начинать большинство backend-проектов в 2026 году. Spoiler alert: это не микросервисы.
Руковожу направлением Java-разработки в FinTech и уже несколько лет преподаю курс по архитектуре в OTUS. За это время я увидел десятки проектов — от стартапов до корпоративных систем. И всё чаще наблюдаю одну и ту же картину: команда из пяти человек с горящими глазами начинает новый продукт и сразу погружается в docker-compose с пятью сервисами, Kafka для событий и service mesh «на будущее». Через три месяца они тонут в complexity, а бизнес требует первую версию. Знакомо?
Сегодня мы пойдём другим путём. Я покажу, как собрать простое, но полноценное монолитное приложение на Spring Boot и Kotlin — тот самый надежный фундамент, который позволит вам запустить MVP за недели, а не месяцы. А в конце расскажу, где можно системно прокачать навыки Kotlin-разработчика, чтобы строить такие системы уже профессионально.
Слон в посудной лавке, или почему все говорят про микросервисы, а вы пока должны выбрать монолит?
Когда в 2016 году Netflix рассказывал на конференциях про свой микросервисный зоопарк, казалось, что будущее за распределёнными системами. Многие, включая меня в начале карьеры, попали в эту ловушку. Мы начинали проект с мыслью: «сделаем как у Netflix» — и тут же начинали пилить сервисы.
Но реальность куда прозаичнее. В 2024-2025 годах на Хабре шли жаркие споры, и тренд начал меняться. Опытные разработчики массово делились историями, как они «вернулись к монолиту» или отложили распил на годы. Цифры говорят сами за себя: для команды до 15 человек накладные расходы на orchestration, межсервисное взаимодействие, трассировку и обеспечение консистентности данных могут увеличить сложность системы на 50-100%, не принося при этом бизнесу ровным счётом никакой пользы на старте.
В одном из fintech-стартапов, в соответствии с техническим заданием заказчика, мы потратили 4 месяца на запуск «идеальной» микросервисной архитектуры. А конкурент за те же 4 месяца на монолите (тоже Spring Boot + Kotlin) выпустил три крупных обновления и первым вышел на рынок. Их CTO потом признался: «Монолит давал нам скорость разработки в 2-3 раза выше. Мы просто успевали больше».
Вывод прост: монолит — не «устаревшая архитектура», а стратегический инструмент. Он позволяет:
Запустить работающий прототип за дни, а не недели.
Иметь один деплой, одну базу данных, один лог — и в 3 раза меньше головной боли при отладке.
Масштабироваться вертикально до десятков тысяч RPS (а этого хватит 95% проектов на первых 3-5 годах жизни).
И когда вы достигаете реальных границ монолита (например, 50+ разработчиков в команде или необходимость независимо масштабировать конкретные компоненты в 100 раз), вы уже имеете работающий продукт, понимание домена и ресурсы для осмысленного перехода к распределённой архитектуре.
Kotlin + Spring Boot: Любовь с первого data class
Почему именно эта связка? Когда я впервые попробовал писать Spring-приложение на Kotlin в 2018 году, это было похоже на прозрение. Всё то, что в Java занимало десятки строк шаблонного кода (геттеры, сеттеры, equals, hashCode, Builder), в Kotlin ужималось в одну строку data class.
Но дело не только в синтаксическом сахаре. Kotlin привносит в экосистему Spring философию безопасности и выразительности.
Null Safety: Компилятор не даст вам сделать
NullPointerException— главного врага джавистов. Spring прекрасно с этим работает.Корутины: Асинхронный код без hell'а колбэков. Spring WebFlux и корутины — это мощность реактивных систем с почти синтаксисом блокирующего кода.
Extension-функции: Вы можете «добавлять» методы к любым классам, включая классы Spring. Хотите, чтобы String валидировался как email?
"user@mail.com".isValidEmail()— и вот вы уже написали утилиту, которая читается как родной метод.
Всё это не просто «удобно». Это меняет подход к разработке: меньше ошибок на этапе компиляции, больше сосредоточенности на бизнес-логике. И Spring Boot, как самый популярный фреймворк в мире Java, полностью адаптировался под Kotlin, предлагая идиоматичную поддержку.
Наш стек для сегодняшнего примера:
Kotlin 1.9+
Spring Boot 3.2+ (с нативной поддержкой Kotlin coroutines)
Spring Data JPA (для работы с БД)
H2 Database (in-memory для простоты, в продакшене — PostgreSQL)
Gradle Kotlin DSL (конфигурация как код, тоже на Kotlin!)
Практика: Собираем User Service за 15 минут
Давайте создадим простое приложение — сервис управления пользователями (User Service). Это будет классический CRUD (Create, Read, Update, Delete) с REST API. Я покажу структуру и ключевые моменты.
1. Структура проекта (Modular Monolith)
Сразу приучим себя к хорошему тону — даже в монолите делаем модульную структуру. Это задел на будущее.

2. Домен: Сущность User
Вот где сияет Kotlin. Вся сущность в 15 строках вместо 50 на Java.
// user/domain/User.kt package com.example.userapp.user.domain import jakarta.persistence.* import java.time.LocalDateTime @Entity @Table(name = "users") data class User( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long? = null, // ID может быть null до сохранения в БД @Column(nullable = false, unique = true) val email: String, @Column(nullable = false) var name: String, // var, потому что имя можно изменить @Column(nullable = false) val createdAt: LocalDateTime = LocalDateTime.now() )
В этом фрагменте:
data class: Автоматически даетequals(),hashCode(),toString(),copy().Дефолтные значения:
id = null,createdAt = LocalDateTime.now()— это удобно и безопасно.Аннотации JPA (
@Entity,@Table): Работают точно так же, как в Java. Spring Data JPA их прекрасно понимает.
3. Слой данных: Репозиторий
С Spring Data JPA создание репозитория — это магия в одну строчку.
// user/infrastructure/UserRepository.kt package com.example.userapp.user.infrastructure import com.example.userapp.user.domain.User import org.springframework.data.jpa.repository.JpaRepository interface UserRepository : JpaRepository<User, Long> { fun findByEmail(email: String): User? }
Мы объявили интерфейс, а Spring сам сгенерирует реализацию со всеми методами CRUD (save, findById, deleteById и т.д.). Метод findByEmail также будет реализован автоматически благодаря convention over configuration. Это называется Derived Query.
4. Бизнес-логика: Сервис
Сервис — это место, где живут правила. Давайте напишем его с использованием возможностей Kotlin.
// user/application/UserService.kt package com.example.userapp.user.application import com.example.userapp.user.domain.User import com.example.userapp.user.infrastructure.UserRepository import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @Service class UserService(private val userRepository: UserRepository) { fun getAllUsers(): List<User> = userRepository.findAll() fun getUserById(id: Long): User? = userRepository.findById(id).orElse(null) @Transactional fun createUser(email: String, name: String): User { // Пример бизнес-правила: email должен быть уникальным if (userRepository.findByEmail(email) != null) { throw IllegalArgumentException("User with email $email already exists") } return userRepository.save(User(email = email, name = name)) } @Transactional fun updateUserName(id: Long, newName: String): User? { return userRepository.findById(id) .map { user -> user.name = newName // Меняем var-поле name userRepository.save(user) } .orElse(null) } @Transactional fun deleteUser(id: Long) { userRepository.deleteById(id) } }
На что здесь обратить внимание:
@Transactional: Spring управляет транзакциями. Если в методе что-то пойдёт не так, все изменения в БД откатятся.Конструктор с private val: Автоматическое внедрение зависимости (Dependency Injection) через первичный конструктор — идиоматичный способ для Kotlin.
mapиorElse: Работа с Optional из Java в стиле Kotlin.
5. Представление: REST Controller
Контроллер — это точка входа для нашего API.
// user/infrastructure/UserController.kt package com.example.userapp.user.infrastructure import com.example.userapp.user.application.UserService import com.example.userapp.user.domain.User import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.* @RestController @RequestMapping("/api/users") class UserController(private val userService: UserService) { @GetMapping fun getAllUsers(): List<User> = userService.getAllUsers() @GetMapping("/{id}") fun getUserById(@PathVariable id: Long): User? = userService.getUserById(id) @PostMapping @ResponseStatus(HttpStatus.CREATED) fun createUser(@RequestParam email: String, @RequestParam name: String): User { return userService.createUser(email, name) } @PatchMapping("/{id}") fun updateUserName(@PathVariable id: Long, @RequestParam name: String): User? { return userService.updateUserName(id, name) } @DeleteMapping("/{id}") @ResponseStatus(HttpStatus.NO_CONTENT) fun deleteUser(@PathVariable id: Long) { userService.deleteUser(id) } }
6. Запуск
Главный класс приложения стандартный:
// UserAppApplication.kt package com.example.userapp import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication @SpringBootApplication class UserAppApplication fun main(args: Array<String>) { runApplication<UserAppApplication>(*args) }
Запустите приложение, и оно будет доступно на http://localhost:8080. Вот и всё! У вас есть работающий backend с API. Вы можете тестировать его через curl, Postman или Swagger UI (если добавите springdoc-openapi-starter-webmvc-ui).
Что дальше? Штрихи, которые делают приложение production-ready
Наш базовый CRUD работает. Но в реальном проекте этого недостаточно. Вот куда обычно движется разработка, и как Kotlin помогает на каждом шагу:
Валидация. Аннотации
@NotBlank,@Emailизjakarta.validationпрекрасно работают с Kotlin. Добавьте@Validв параметры контроллера.Обработка ошибок. Создайте
@ControllerAdviceкласс. Используйтеsealed class(продвинутая фича Kotlin) для моделирования разнотипных ошибок API.Безопасность. Подключите Spring Security. Kotlin DSL для конфигурации Security (http { ... }) читается как история на чистом английском.
Логирование. Используйте
log property, которую предоставляет Kotlin, или экстеншены вроде log.info { "Создан пользователь: $email" } (с ленивым вычислением строки).
Мой ход мысли на этом этапе обычно такой: сначала я делаю самый простой работающий вариант, как выше. Затем добавляю валидацию, потому что увидел в логах ConstraintViolationException. Потом — глобальный обработчик ошибок, чтобы клиент получал красивые JSON-ошибки, а не стектрейсы. И так, итеративно, feature за feature.
Заключение: монолит как старт, Kotlin как суперсила
Мы с вами собрали полноценный backend-сервис на Spring Boot и Kotlin буквально за полчаса. Это и есть сила монолита: скорость, простота, концентрация на бизнес-ценности. Вы не тратите время на настройку десятка вспомогательных сервисов. Вы пишете код, который решает задачи пользователя.
Kotlin в этой связке — не просто «более лаконичная Java». Это язык, который заставляет думать о null-безопасности, поощряет иммутабельность и предоставляет инструменты (data class, sealed class, extensions, корутины) для написания более надёжного и выразительного кода с меньшими усилиями.
Но это только начало пути. В реальном проекте вам быстро понадобятся:
Работа с несколькими источниками данных (БД, кеш, очереди).
Сложная бизнес-логика с транзакциями.
Асинхронная обработка через корутины или Kafka.
Написание интеграционных и модульных тестов.
Оптимизация производительности и работы с памятью в JVM.
Всему этому можно научиться методом проб и ошибок, растянув процесс на годы. А можно — системно и под руководством практикующих экспертов.
На курсе "Kotlin Backend Developer. Professional" мы не просто повторяем документацию. Мы разбираем:
Как проектировать отказоустойчивые и масштабируемые приложения с самого начала (даже монолиты).
Глубокую работу с Spring Framework 6+ и Spring Boot 3+ в контексте Kotlin.
Построение архитектуры: когда и как правильно «распиливать» монолит, как работать с событиями и сообщениями.
Все инструменты современного бэкенд-разработчика: Docker, Kubernetes, мониторинг, профилирование.
Этот курс — для тех, кто хочет не просто писать код, а строить системы. Системы, которые будут служить годами, масштабироваться под нагрузку и становиться основой бизнеса.
Если вас заинтересовал подход Kotlin + Spring Boot и вы хотите изучить все тонкости профессиональной backend-разработки, приглашаю на открытый урок «Разработка монолитного приложения со Spring», который пройдет 4 февраля в 19:00 в рамках курса. Участие бесплатное, нужна регистрация.
