#typescript #domain-driven-design
Вопрос:
Я много изучал проверки ввода, и я был немного сбит с толку, многие указывают на то, чтобы оставить проверки размера типа, типа конкретной переменной в домене, чтобы выполнить проверку таким образом, чтобы не привести к утечке знаний о домене, и с этим, поскольку я использую typescript, я подумал о статической функции для создания моего агрегата и использовать статическую функцию с именем canBuild, чтобы проверить, возможно ли создать агрегат
подобный этому:
export class PersonAggregrate extends Entity<IPersonProps> {
private constructor(props: IPersonProps, id?: string) {
super(props, id)
}
private static canBuild(props: IPersonJSON): IErrorModel[] {
let errors = [] as IErrorModel[]
if (typeof props.firstName !== 'string') errors.push({})
if (typeof props.lastName !== 'string') errors.push({})
if (props.firstName.length < 4) errors.push({})
if (props.lastName.length < 2) errors.push({})
return errors
}
public static build(
props: IPersonJSON amp; { id?: string },
): Either<IErrorModel[], Person> {
const hasErrs = this.canBuild(props)
const user = User.build(props.user)
if (user.isLeft()) {
hasErrs.push(...user.value)
return left(hasErrs)
}
if (hasErrs.length > 0) return left(hasErrs)
const person = new Person({ ...props, user: user.value }, props.id)
return right(person)
}
}
сущность пользователя:
export class User extends Entity<IUserJSON> {
private constructor(props: IUserJSON, id?: string) {
super(props, id)
}
private static canBuild(user: IUserJSON) {
let errors = [] as IErrorModel[]
if (typeof user.login !== 'string') errors.push({})
if (typeof user.password !== 'string') errors.push({})
if (user.refreshToken amp;amp; !validator.isJWT(user.refreshToken)) {
errors.push({})
}
return errors
}
public static build(
props: IUserJSON amp; { id?: string },
): Either<IErrorModel[], User> {
const canBuild = this.canBuild(props)
if (canBuild.length > 0) left(canBuild)
const user = new User(props, props.id)
return right(user)
}
}
моя пользовательская сущность является частью моего объединенного лица
Сделал ли я также следующее в своей команде, чтобы создать объединение:
export class CreatePersonCommand implements ICommand {
private readonly id: string
private readonly login!: string
private readonly password!: string
private readonly personId!: string
private readonly firstName!: string
private readonly lastName!: string
constructor(person: Omit<IPersonJSON amp; IUserJSON, 'user' | 'personId'>) {
this.id = v4()
this.personId = this.id
this.login = person.login
this.password = person.password
this.firstName = person.firstName
this.lastName = person.lastName
}
public CanExecute(): boolean {
let errors = [] as IErrorModel[]
for (let field in this) {
if (!this[field]){
errors.push({ code: 215, message: `Required field: ${field}` })
}
}
if (errors.length > 0) throw new BadRequestERROR({ errors })
return errors.length <= 0
}
}
чтобы не разрешать отправку данных сущности без свойств агрегата
export class CreatePersonCommand implements ICommand {
private readonly id: string
private readonly login!: string
private readonly password!: string
private readonly personId!: string
private readonly firstName!: string
private readonly lastName!: string
constructor(person: Omit<IPersonJSON amp; IUserJSON, 'user' | 'personId'>) {
this.id = v4()
this.personId = this.id
this.login = person.login
this.password = person.password
this.firstName = person.firstName
this.lastName = person.lastName
}
public CanExecute(): boolean {
let errors = [] as IErrorModel[]
for (let field in this) {
if (!this[field]){
errors.push({ code: 215, message: `Required field: ${field}` })
}
}
if (errors.length > 0) throw new BadRequestERROR({ errors })
return errors.length <= 0
}
}
в моей совокупности я не использую ошибки ввода, потому что это просто ошибки входных данных, но я не знаю, следует ли мне рассматривать это (пустые данные как необработанные входные данные, поскольку они не отправляются)
, и на моем посреднике я использую CanExecute перед выполнением команды:
public publish<T extends ICommand>(command: T): Promise<any> {
if (!command) throw new InvalidCommandException()
const handler = this.registry.get(command.constructor.name)
if (!handler) throw new HandlerNotFoundException(command.constructor.name)
if(!command.CanExecute()) throw new InvalidCommandException()
return handler.execute(command)
}
Я хотел бы знать, правильно ли это или есть лучший вариант?
Комментарии:
1. Я думаю, что вы можете найти это сообщение в блоге очень полезным.
2. @plalx эй, братан, спасибо тебе большое, это многое прояснило, я шел по тому же пути, но по ошибке, ты хочешь создать ответ для меня, чтобы я проголосовал положительно?
3. это очень помогает мне в моих вопросах, спасибо вам .
4. Я приглашаю вас ответить на ваш собственный вопрос с помощью полученных вами знаний 😉 Я рад, что это было полезно! Это определенно один из лучших постов, которые я читал о проверке.