class-validator неожиданно запускает проверку с помощью createQueryBuilder

#typescript #validation #typeorm #restify #class-validator

#typescript #проверка #typeorm #повторная проверка #class-validator

Вопрос:

Я использую Typeorm в сочетании с class-validator, поэтому я определил объект, подобный этому:

 import {
    Entity,
    PrimaryGeneratedColumn,
    Column,
    BaseEntity,
    BeforeInsert,
    BeforeUpdate,
    &etRepository
} from "typeorm";
import {
    validateOrReject,
    IsDefined,
} from "class-validator";
import errors from 'restify-errors';

@Entity()
export class License extends BaseEntity {
    @PrimaryGeneratedColumn('uuid')
    public id!: strin&;

    @Column({ nullable: false })
    @IsDefined({ messa&e: 'name field was not provided' })
    public name!: strin&;

    @Column({ nullable: false })
    @IsDefined({ messa&e: 'description field was not provided' })
    public description!: strin&;

    @BeforeInsert()
    @BeforeUpdate()
    async validate() {
        await validateOrReject(this, { skipUndefinedProperties: true });

        // Check if license already exists
        if ((await &etRepository(License).count({ name: this.name }) &&t; 0))
            throw new errors.BadRequestError(`There is already a license with name of ${this.name}`);
    }
}
  

Я также определил промежуточное программное обеспечение, которое запускает &etMany для извлечения данных из Entity<T&&t; репозитория, например:

 export default (entity: any) =&&t; async (req: Request, res: Response, next: Next) =&&t; {
    const repository = &etRepository(entity);
    const query = repository.createQueryBuilder(`${entity}`);

    // Get query params
    for (const propName in req.params) {
        if (req.params.hasOwnProperty(propName)) {
            query.where(`${propName} = :param`, { param: req.params[propName] });
        }
    }

    // Pa&ination
    const pa&e = parseInt(req.query.pa&e, 10) || 1;
    const limit = parseInt(req.query.limit, 10) || 25;
    const startIndex = (pa&e - 1) * limit;
    const endIndex = pa&e * limit;

    const [result, total] = await query
        .skip(startIndex)
        .take(endIndex)
        .&etManyAndCount();

    res.send({
        "success": true,
        "data": result,
        "count": total,
        "messa&e": null
    });

    next();
};
  

когда я запускаю промежуточное программное обеспечение, функция async validate() также запускается, но этого не должно быть, потому что я получаю данные, не вставляя и не обновляя их.
Фактически, когда validate метод запускается, Typeorm генерируется эта ошибка:

«Ошибка запроса: ER_PARSE_ERROR: у вас ошибка в вашем синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса для использования near ‘ — это уже лицензия с именем $ {this.name } );rn });rn }rn} . id A’ в строке 12″

Если я прокомментирую функцию validate , данные будут правильно возвращены из промежуточного программного обеспечения.

Что происходит? Это ошибка библиотеки?

Ответ №1:

Похоже, что ваше промежуточное программное обеспечение использует следующее сообщение в вашем запросе: There is already a license with name of ${this.name} . Без дополнительных указаний на то, как вы используете свое промежуточное программное обеспечение с restify (инструкция server.use), трудно сказать, как и почему эта полезная нагрузка сообщения об ошибке заканчивается в вашем запросе промежуточного программного обеспечения, но вы должны проверить в этом направлении.

С другой стороны, если вам нужно обеспечить уникальность имени лицензии, вы можете захотеть объявить уникальный ключ на name со следующими обозначениями вместо использования ручной проверки:

 @Column({ nullable: false, unique: true })
public name!: strin&;
  

Пожалуйста, найдите дополнительную информацию в документации typeorm: https://&ithub.com/typeorm/typeorm/blob/master/docs/decorator-reference.md#column