Обновить

Многие используют подход API First в проектировании систем, но зачастую даже не задумываются, что порождают таким образом сервисы с анемичными доменными моделями, проектируя по сути REST-обертки над базой данных с отсутствием какой-либо бизнес-логики.

API First и Богатая доменная модель не являются взаимоисключающими понятиями, если правильно выстроить процесс и архитектуру.

Главная проблема: API First фокусируется на контрактах внешнего мира, что часто приводит к созданию DTO/Model классов, которые являются чистыми структурами данных без поведения (анемичная модель).

API First — это про контракты, а не про реализацию. Не позволяйте инструментам кодогенерации диктовать структуру вашей доменной модели!

Правильный workflow:

1. API Design First: Создайте/обновите OpenAPI спецификацию.

2. Генерация DTO: Сгенерируйте или создайте классы для API‑контрактов.

3. Projection First: Спроектируйте доменную модель независимо от DTO, фокусируясь на поведении и инвариантах.

4. Создание Mapping Layer: Напишите преобразователи между DTO и Domain Objects.

5. Реализация Application Service: Тонкий слой, который координирует работу домена.

Стек технологий, который помогает:

MapStruct: Для автоматизации маппинга между DTO и Domain
JUnit 5: Для тестирования доменной логики
OpenAPI Generator: Для автоматической генерации DTO из спецификации
ArchUnit: Для проверки архитектурных правил (например, запрет на анемичные модели)

// ArchUnit тест, проверяющий, что в доменных классах есть поведение
@ArchTest
static final ArchRule domain_models_should_have_business_methods = 
    classes()
        .that().resideInPackage("..domain..")
        .and().areAnnotatedWith(Entity.class)
        .should().containAnyMethodsThat(
            DescribedPredicate.describe(
                "have business methods", 
                method -> !method.getName().startsWith("get") && 
                         !method.getName().startsWith("set")
            )
        );
Теги:
-1
Комментарии0

Публикации

Ближайшие события