我一直在研究有关输入验证的很多内容,但我有点困惑,许多人表示将验证类型大小、域中特定变量的类型,以不会导致验证的方式执行验证领域知识的泄漏 很好,因为我正在使用打字稿,我想到了一个静态函数来创建我的聚合并使用一个名为 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 & { 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 && !validator.isJWT(user.refreshToken)) {
errors.push({})
}
return errors
}
public static build(
props: IUserJSON & { 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 & 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 & 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
}
}
在我的汇总中,我不使用 throw in errors 因为它们只是输入数据错误,但我不知道是否应该考虑它(空数据作为未处理的输入数据,因为它们没有被发送) 在我的中介上,我在执行命令之前使用 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)
}
我想知道这是正确的还是有更好的选择?