Nest Js CQRS - совокупная установка с существующими сущностями TypeORM - PullRequest
3 голосов
/ 12 января 2020

Итак, здесь есть официальный пример

https://github.com/kamilmysliwiec/nest-cqrs-example

, и я попытался создать свой собственный для трех простых функций:

  • Выборка всех пользователей
  • Выборка одного пользователя по идентификатору
  • Создание пользователя

Я использую TypeORM и имею базовую c сущность пользователя. Поэтому на основе официального примера кода я создал обработчик команд для создания пользователей

@CommandHandler(CreateUserCommand)
export class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
  constructor(
    private readonly usersRepository: UsersRepository,
    private readonly eventPublisher: EventPublisher,
  ) {}

  public async execute(command: CreateUserCommand): Promise<void> {
    const createdUser: User = await this.usersRepository.createUser(
      command.username,
      command.password,
    );

    // const userAggregate: UserAggregate = this.eventPublisher.mergeObjectContext(
    //   createdUser,
    // );
    // userAggregate.doSomething(createdUser);
    // userAggregate.commit();
  }
}

Все, что он делает - это сохранение нового пользовательского объекта в базе данных. Но сейчас я не понял, что делать с агрегатом пользователей. При объединении контекста объекта я не могу передать созданный пользовательский объект. И еще я не знаю, какие логики c должны обрабатываться агрегатом. Итак, основываясь на этой совокупности пользователей

export class User extends AggregateRoot {
  constructor(private readonly id: string) {
    super();
  }

  public doSomething(user: UserEntity): void {
    // do something here?

    this.apply(new UserCreatedEvent(user));
  }
}

, я знаю, что могу вызвать событие, создать нового пользователя и отправить его в историю. Но разве это единственное, за что он отвечает?

Я создал репозиторий для воспроизведения, упомянутые файлы кода связаны здесь

Совокупность пользователей:

https://github.com/matthiashermsen/temp-cqrs/blob/master/src/users/models/user.model.ts

Создать обработчик пользовательских команд:

https://github.com/matthiashermsen/temp-cqrs/blob/master/src/users/commands/handlers/create.user.handler.ts

Так как мне настроить агрегат пользователей и создать обработчик пользователей правильно?

При передаче в созданную сущность я получаю сообщение об ошибке типа

Аргумент типа 'Пользователь' не может быть назначен параметру типа 'Агрегат * Root'. Типу «Пользователь» не хватает следующих свойств из типа «Агрегат Root»: autoCommit, publi sh, commit, uncommit и еще 7.ts (2345)

, что имеет смысл, поскольку сущность TypeORM расширяется BaseEntity, а совокупность расширяется AggregateRoot. К сожалению, официальный пример не показывает, как работать с агрегатами и объектами базы данных.

1 Ответ

3 голосов
/ 13 января 2020

Эта doSomething функция, о которой вы упоминаете, предназначена именно для того, что вы описали, для генерации события. Я не вижу никаких дополнительных возможностей для этого, потому что мы перевели все бизнес-логи c с «моделей» на «услуги», так что да.

Ответ на комментарий, потому что комментарии имеют ограничения

Вместо:

    const createdUser: User = await this.usersRepository.createUser(
      command.username,
      command.password,
    );

    const userAggregate: UserAggregate = this.eventPublisher.mergeObjectContext(
      createdUser,
    );
    userAggregate.raiseUserCreatedEvent(createdUser);

Do

    const userAggregate: UserAggregate = this.eventPublisher.mergeObjectContext(
      await this.usersRepository.createUser(
        command.username,
        command.password,
      )
    );
    userAggregate.raiseUserCreatedEvent();

, затем в user.model do:

public raiseUserCreatedEvent(): void {
    this.apply(new UserCreatedEvent(this));
  }

кстати, если вы избавитесь от наберите : User в строке:

const createdUser: User = await this.usersRepository.createUser(

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

...