Чистый микроблог. Команда и Событие

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

Для начала - опять абстракции. Обычно у нас есть команда, ее кто-то обрабатывает (handler) и сообщает о результатах работы - испускает событие (event). Учитываем, что команде абсолютно все равно кто именно ее будет обрабатывать, а событию - кто его будет испускать. И команда и событие - это сообщения, которые меняют мир. И в том числе - это данные нашего приложения.

from dataclasses import dataclass

@dataclass(frozen=True)
class Message:
    pass


@dataclass(frozen=True)
class Event(Message):
    pass


@dataclass(frozen=True)
class Command(Message):
    pass

Сообщения сделаны датаклассами исключительно для удобства разработки.

Датаклассы нагляднее инициализировать, указание frozen=True, защитит от случайных попыток изменения(сообщения иммутабельны) и даст удобную репрезентацию, которую можно скопировать и инициализировать объект снова.

Ну и для читабельности команды начинать с глагола - RegisterCustomer, а события заканчивать глаголом в прошедшем времени CustomerRegistered.

Настала пора написать нашу первую команду и соответсвующее событие. Как это обычно происходит? Приходит представитель заказчика и говорит:

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

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

class PublishPost(Command):
    id: PostId
    customer_id: CustomerId
    text: PostText

class PostPublished(Event):
    id: PostId
    customer_id: CustomerId
    text: PostText

Может показаться странным, что идентификатор поста уже есть еще до его фактического создания где-то в хранилище данных. Мне кажется, что генерировать идентификаторы сущностей где-то там далеко на клиенте - идея хорошая. Это позволяет строить идепотентные API. Поэтому оставим так.

Наверное, наличие текста поста в результирующем событии тоже спорно. Полагаю, оно позволит быстрее оповестить заинтересованных, ну и речь о микроблогинге. Если под постом понимать что-то типа муры, которую вы читаете, то лучше, конечно, в событиях такое не передавать.

Теперь, настала пора сделать наш первый обработчик команды. Но об этом - в следующей серии.

<2023-01-22 Sun>

Author: Nikita Mistiukov <me@nekifirus.com>

Created: 2023-01-27 Fri 00:01

Validate