Домены как основа проектирования

Сейчас, когда мы разобрали все элементы, можно немного откатиться назад и посмотреть, чем мы руководствовались, когда разбивали систему на блоки. 

Самый простой вариант — отталкиваться от функциональных требований.

В каких-то моментах мы увидим, что блоки пересекаются — это круто! Значит, ты нашел элементы, которые не нужно дублировать. Например, сервис для обновления локации пользователя будет использоваться практически всегда для всех пользователей — выносим его!

Это и есть домены — автономные элементы бизнес-логики с чёткими границами.

Главное, не путай домены с микросервисами. Домен — это логическая единица бизнес-логики, а микросервис — её физическая реализация.

Давай посмотрим на несколько схем взаимодействий для нашей системы, которые подсказывают, на какие блоки будем ее разбивать.

Сценарий 1: Отправка сообщения

  1. Пользователь отправляет сообщение → API Gateway (HTTP/gRPC).
  2. API Gateway → Сервис приема сообщений (запись в очередь Kafka/RabbitMQ).
  3. Очередь → Сервис обновления метаданных (обновляет последнее сообщение в чате).
  4. Сервис отправки → KV-БД (поиск коннекта получателя) → WebSocket.

Сценарий 2: Просмотр стартового экрана

  1. Запрос списка чатов → Сервис чатов.
  2. Сервис чатов → PostgreSQL (шардирование по user-id).

Сценарий 3: Регистрация пользователя

  1. Запрос → Сервис пользователей.
  2. Сервис пользователей → SQL DB → Данные реплицируются в другие ЦОДы (через мастер-мастер синхронизацию).

Но как проверить, что домены выделены верно? Тут вам два лайфхака — тест на независимость и тест на простоту.  

Тест на независимость: изменения в одном домене не ломают другие. Например, при изменении домена, который отвечает за пользователей, не происходит изменений в домене на отправку сообщений.

Тест на простоту: ты можешь описать домен одной фразой без «и». То есть формулировка «Отвечает за пользователей и рассылки» тест не проходит, а вот «управляет жизненным циклом заказа» — норм. 

При этом не нужно слишком мельчить, когда ты выделяешь домены. «Отображение платежей» — слишком маленький логический блок, лучше сразу брать «Платежи» целиком.  

Суперстатья от Uber, где они рассказывают про домены