Практическое задание#

В первом модуле:

  • Выбрали архитектурный подход (монолит / модульный монолит / микросервисы)
  • Выделили домены
    • Заказы
    • Оплата
    • Каталог
    • Доставка
    • Уведомления
  • Определили границы сервисов и владение данными
  • Зафиксировали решение через ADR
  • Нарисовали контекстную и компонентную схемы.

Во втором модуле мы оживляем эти границы - через реальные контракты взаимодействия между доменами.

Задание#

Система заказов развивается. Появляется требование.

При изменении статуса заказа система уведомлений должна получать событие,
а внешние клиенты - иметь стабильный HTTP API для чтения заказа.

Это приводит к двум типам контрактов:

  • HTTP контракт для чтения состояния заказа
  • Event контракт для реакции других доменов

Часть 1. Контракты домена «Заказы» (HTTP)#

Спроектировать публичный HTTP контракт сервиса заказов.

Требования

  • Клиенты
    • Frontend
    • Сервис уведомлений (read-only)
  • Операции
    • Получить заказ по id
    • Получить список заказов пользователя
  • Контракт должен быть
    • Версионируемым
    • Допускать расширение модели
    • Пригодным для кодогенерации

Практика

  1. Создать файл orders-api.yaml
  2. Описать
    • /orders/{id}
    • /orders?userId={} или /orders/users/{id}
  3. Использовать
    • Явные типы
    • Enums для статусов
    • Optional поля
  4. Сгенерировать для своего языка программирования (java, golang, …)
    • DTO модели
    • Http клиент
  5. Используя openapi-generator или другие инструменты кодогенерации
  6. Артефакты
    • Сгенерированные модели
    • 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 заказов, реагирует только на события асинхронно

Практика

  1. Спроектировать контракт события: OrderStatusChanged
  2. Создать orders-events.yaml
  3. Описать
    • Канал order.status.changed
    • Payload события
    • Producer / consumer
  4. Сгенерировать для своего языка программирования (java, golang, …)
    • Event DTO
    • Consumer interface / handler
  5. Артефакты
    • Схема события
    • Сгенерированные модели
    • Пример обработчика (псевдокод)

Пример 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 из ответа

Практика. Для каждого изменения

  1. Определить
    • Safe / unsafe
  2. Выбрать стратегию
    • Расширение
    • Новая версия
    • Миграция
  3. Артефакты
    • Решение по каждому кейсу и обоснование

Контакты#

Поддержать автора