vendredi 12 mars 2021

Typescript: event source and ddd

Hello I am studying about event source and I have difficulty in how to structure the pattern with typescript.

Domain entity:

export class User implements IState {
  index: number;
  public readonly name: string;
  public readonly email: string;

  private constructor (name: Name, email: Email) {
    this.name = name.value
    this.email = email.value
    Object.freeze(this)
  }
  static create(
    dto: UserStruct
  ): Either<InvalidNameError | InvalidEmailError, User> {
    const name: Either<InvalidNameError, Name> = Name.create(dto.name);
    const email: Either<InvalidEmailError, Email> = Email.create(dto.email);
    if (name.isLeft()) return left(name.value);
    if (email.isLeft()) return left(email.value);
    const user = new User(name.value, email.value);
    return right(user);
  }
}

command:

export interface ICommand {
    id: string;
    date: Date;
}


export interface ICreateUserCommand extends ICommand{
  state: UserStruct
}

export class CreateUserCommand implements ICreateUserCommand {
  public readonly id: string;
  public readonly date: Date;
  public readonly state: UserStruct;
  constructor({id,date,state}: ICreateUserCommand){
    this.id = id;
    this.date = date;
    this.state = state;
  }
}

Event:

export interface IEvent {
    id: string;
    date: Date;
}
export interface IUserCreatedEvent extends IEvent {
  name: string
  email: string
}

export class UserCreated implements IUserCreatedEvent {
  public readonly id: string;
  public readonly date: Date;
  public readonly name: string;
  public readonly email: string;
  constructor({date,state,id}:ICreateUserCommand){
    this.id = id
    this.date = date
    this.email = state.email
    this.name = state.name
  }
}

But I have a question about how I call this command in my service, who would be responsible for creating the user instance so that I can save the user state and the event in my database. I should in my static method of the User: User.create class and then I create my user instance? or should i create this instance at the event?

export class CreateUserService {
  constructor(private commandHandler:CreateUserCommandHandler){}
  async execute(dto: UserStruct){
    const user = User.create(dto)
    this.commandHandler.execute(new CreateUserCommand(her usr instance ???))
  }
}

//edit:

responsible for calling the function to change the current state of the entity and commit the event (save the event in an event db) my command handler?

like this:

export class CreateUserCommandHandler extends ICreateUserCommandHandler {
  constructor(){
    super()
  }
  async execute(command: ICreateUserCommand): Promise<IUserCreatedEvent> {
    console.log(`Aync creating user`);
    const { state } = command;
    const user = User.create(state);
    if(user.isLeft()) throw new Error(`Invalid User`);
    // her i change state from user and it is ok commit my event?
  }
}

Aucun commentaire:

Enregistrer un commentaire