Практическое задание#
В первом модуле:
- Выбрали архитектурный подход (монолит / модульный монолит / микросервисы)
- Выделили домены
- Заказы
- Оплата
- Каталог
- Доставка
- Уведомления
- Определили границы сервисов и владение данными
- Зафиксировали решение через ADR
- Нарисовали контекстную и компонентную схемы.
Во втором модуле мы оживляем эти границы - через реальные контракты взаимодействия между доменами.
Задание#
Система заказов развивается. Появляется требование.
При изменении статуса заказа система уведомлений должна получать событие,
а внешние клиенты - иметь стабильный HTTP API для чтения заказа.Это приводит к двум типам контрактов:
- HTTP контракт для чтения состояния заказа
- Event контракт для реакции других доменов
Часть 1. Контракты домена «Заказы» (HTTP)#
Спроектировать публичный HTTP контракт сервиса заказов.
Требования
- Клиенты
- Frontend
- Сервис уведомлений (read-only)
- Операции
- Получить заказ по id
- Получить список заказов пользователя
- Контракт должен быть
- Версионируемым
- Допускать расширение модели
- Пригодным для кодогенерации
Практика
- Создать файл
orders-api.yaml - Описать
/orders/{id}/orders?userId={}или/orders/users/{id}
- Использовать
- Явные типы
- Enums для статусов
- Optional поля
- Сгенерировать для своего языка программирования (java, golang, …)
- DTO модели
- Http клиент
- Используя
openapi-generatorили другие инструменты кодогенерации - Артефакты
- Сгенерированные модели
- README с инструкцией генерации
- ADR: по фиксации подхода
Пример фрагмента
order:
type: object
required:
- id
- status
- createdAt
properties:
id:
type: string
status:
type: string
enum: [CREATED, PAID, SHIPPED, CANCELLED]
totalPrice:
type: number
createdAt:
type: string
format: date-timeЧасть 2. Контракты событий (уведомления о статусе заказа)#
Сервис уведомлений не должен
- Ходить в БД заказов
- Синхронно дергать API заказов, реагирует только на события асинхронно
Практика
- Спроектировать контракт события:
OrderStatusChanged - Создать
orders-events.yaml - Описать
- Канал
order.status.changed - Payload события
- Producer / consumer
- Канал
- Сгенерировать для своего языка программирования (java, golang, …)
- Event DTO
- Consumer interface / handler
- Артефакты
- Схема события
- Сгенерированные модели
- Пример обработчика (псевдокод)
Пример payload
OrderStatusChanged:
type: object
required:
- orderId
- oldStatus
- newStatus
- changedAt
properties:
orderId:
type: string
oldStatus:
type: string
newStatus:
type: string
changedAt:
type: string
format: date-timeЧасть 3. Развитие контрактов#
Бизнес приходит с новыми требованиями:
- Добавить
deliveryType(вид доставки) - Добавить новый статус
RETURNED - Убрать поле
totalPriceиз ответа
Практика. Для каждого изменения
- Определить
- Safe / unsafe
- Выбрать стратегию
- Расширение
- Новая версия
- Миграция
- …
- Артефакты
- Решение по каждому кейсу и обоснование