NestJS自定义转换管道,带有参数和注入的TypeOrm数据源

huangapple go评论109阅读模式
英文:

NestJS custom transform pipe with parameters and injected TypeOrm dataSource

问题

我正在尝试编写用于实体ID验证的自定义管道。想法是接受实体类作为参数,从路由获取ID,并验证是否存在具有该ID的实体。

所以我有一个端点:

@Post('track/:id')
addTrack(
  @Param('id', ParseUUIDPipe, new EntityIdValidationPipe(Track)) id: string,
) {
  return this.favsService.addTrack(id);
}

这是自定义管道:

@Injectable()
export class EntityIdValidationPipe implements PipeTransform {
  constructor(private entityClass: EntityClassOrSchema) {}

  async transform(id: string, metadata: ArgumentMetadata): Promise<string> {
    // 这里我需要访问TypeOrm的DataSource,
    // 但我不知道如何注入它
    return id;
  }
}

正如你上面看到的,我在验证管道中使用了new关键字来传递参数。在transform方法中,我想要做类似这样的事情:

this.dataSource.getRepository(this.entityClass).findOneBy({ id }) 

但我不能这样做,因为我不知道如何注入TypeOrm的DataSource对象。

所以基本上我的问题是:我如何同时传递参数给自定义的transform管道并在管道中使用DI(依赖注入)?

谢谢。

英文:

I'm trying to write custom pipe for entity id validation. The idea is to accept entity class as parameter, get id from route and validate whether entity with such id exists.

So i have an endpoint:

@Post(&#39;track/:id&#39;)
addTrack(
  @Param(&#39;id&#39;, ParseUUIDPipe, new EntityIdValidationPipe(Track)) id: string,
) {
  return this.favsService.addTrack(id);
}

and here is custom pipe:

@Injectable()
export class EntityIdValidationPipe implements PipeTransform {
  constructor(private entityClass: EntityClassOrSchema) {}

  async transform(id: string, metadata: ArgumentMetadata): Promise&lt;string&gt; {
    // here i need to access TypeOrm&#39;s DataSource,
    // but i dont know how to inject it
    return id;
  }
}

As you can see above i'm using validation pipe with new keyword to pass an argument.
In transform method i want to do something like this:

this.dataSource.getRepository(this.entityClass).findOneBy({ id }) 

But i cant do it because i dont know how to inject TypeOrm DataSource object.

So basically my question is: How can i pass parameters to custom transform pipe and use DI in that pipe simultaneously?

Thank you.

答案1

得分: 1

听起来你实际想要做的是创建一个mixin管道,这是一个返回类引用的函数,以便Nest仍然可以注入数据源。它看起来像这样:

export const EntityIdValidationPipe = (entityClass: EntityClassOrSchema) => {
  @Injectable()
  class EntityIdValidationMixinPipe {
    constructor(@InjectDataSourcec() private readonly dataSource: DataSource) {}
    async transform(id: string, metadata: ArgumentMetadata): Promise<string> {
      const entity = await this.dataSource.getRepository(entityClass).findOneBy({ id }) 
      // validate entity
      return id;
    }
  return EntityIdValidationMixinPipe;
}

对于其他参考,请查看Nest的AuthGuard()FileInterceptor

英文:

Sounds like what you are actually wanting to do is create a mixin pipe, a function that will return a class reference so that Nest can still inject the datasource. It would look something like this:

export const EntityIdValidationPipe = (entityClass: EntityClassOrSchema) =&gt; {
  @Injectable()
  class EntityIdValidationMixinPipe {
    constructor(@InjectDataSourcec() private readonly dataSource: DataSource) {}
    async transform(id: string, metadata: ArgumentMetadata): Promise&lt;string&gt; {
      const entity = await this.dataSource.getRepository(entityClass).findOneBy({ id }) 
      // validate entity
      return id;
    }
  return EntityIdValidationMixinPipe;
}

For other references, check out Nest's AuthGuard() and FileInterceptor

huangapple
  • 本文由 发表于 2023年6月8日 00:32:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76425410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定