如何在 Nestjs 中获取嵌套的 URL 查询

Posted

技术标签:

【中文标题】如何在 Nestjs 中获取嵌套的 URL 查询【英文标题】:How to get nested URL query in Nest.js 【发布时间】:2021-12-12 13:45:53 【问题描述】:

我有 NestJS 应用程序,我必须从 URL 获取查询。问题是我的 creationDate 是一个对象,我无法通过 @Query 将它作为嵌套对象。

以下是路线示例:

xxx/yyy/orders?key1=value&key2=value&key3=value&createdAt[lte]=2021-07-01&createdAt[gte]=2011-03-30&orderBy=desc&limit=500

我正在尝试将 createdAt[lte] 和 createdAt[gte] 作为嵌套对象

export interface QueryI 
key1: string;
key2: string;
key3: string;
key4: string;
createdAt: 
    lte: string,
    gte: string,

orderBy: 'desc' | 'asc';
limit: number;

这是我的控制器:

@Get('route')
getAll(
    @Query() query: QueryI): Promise<void>  
    return this.myService.findAll(query);

但这给了我以下结果



key1: 'value',        
  key2: 'value',
  key3: 'value',       
  key4: 'value',
  'createdAt[lte]': 'some date',
  'createdAt[gte]': 'some date',
  orderBy: 'desc',
  limit: '500'


我尝试过 JSON.stringify 并在 SOW 上咨询过类似的问题,但没有运气。

谢谢

【问题讨论】:

你的 HTTP 引擎是什么?你通过什么发送请求?它可能没有正确编码查询参数 不知道你说的HTTP引擎是什么意思,但是我用postman来测试一下。 我所说的 HTTP 引擎,是指 express 或 fastify,它们是 Nest 可以使用的底层引擎。使用curl 发送有效的请求:curl 'http://localhost:3000/?key1=value1&amp;key2%5Binner1%5D=hello&amp;key2%5Binner2%5D=world',而无效:'http://localhost:3000/?key1=value&amp;key2[inner1]=hello&amp;key2[inner2]=world'。所以就像我说的,这可能是一个查询参数编码问题 我使用 Fastify 和 NestJs。我无法更改即将到来的 URL 的编码。我正在构建一个连接 3 个不同 API 的连接器。这是我无法控制的传入请求。我有机会让它工作吗?谢谢 【参考方案1】:

QueryI 从接口切换到类。

正在使用 NestJS 7。

用于测试的网址

http://localhost:3000/api/v1/store/search?nestedObj[key1]=yolo&amp;nestedObj[key2]=sup%20bruh&amp;el=test

已使用 DTO

export class TestDto 
  el: string;
  nestedObj: 
    key1: string;
    key2: string;
  ;

控制器

@Controller('v1/store')
@UsePipes(new ValidationPipe( exceptionFactory: getFormattedErrors ))
@UseFilters(DomainExceptionFilter)
export class TestController
@Get('search')
  public async searchStore(@Query() testDto: TestDto) 
    console.log(testDto);
    return 1;
  

// Console log -  nestedObj:  key1: 'yolo', key2: 'sup bruh' , el: 'test' 

【讨论】:

感谢您的回答,但这不起作用,我不知道为什么......除非装饰器对其工作很重要,否则请添加导入。编辑:我的 nestjs/common 是 8.0.0 您使用了验证管道吗?如果没有,请使用一个,然后尝试。 我刚刚添加了这个@UsePipes(new ValidationPipe( transform: true )),它仍然没有工作......我是NestJS的新手,你能给我更多信息请 【参考方案2】:

编辑

最后我实现了不同的类并使用@Pipe 来验证我的查询:这是代码:

管道.ts

@Injectable()
export class ValidateQueryPipe implements PipeTransform 
  transform(value: any, metadata: ArgumentMetadata) 
    let incomingQuery = value as IncomingQuery;
    let mappedQuery = new QueryParameters()
    mappedQuery.key1 = incomingQuery.key1
    mappedQuery.key2= incomingQuery.key2
    // other mapped valus
    mappedQuery.createdAt = new CreatedAt(incomingQuery['createdAt[lte]'], incomingQuery['createdAt[gte]'])        
    return mappedQuery;
  

controller.ts

@Get(':someurl/someurl')
getAllOrders(
    @Query(ValidateQueryPipe) query: QueryParameters): Promise<Observable<any>>  
    return this.service.findAll(erpCode, query);

查询参数.ts

import  CreatedAt  from "./created-at";

export class QueryParameters 
    key1: string;
    key2: string;
    createdAt: CreatedAt;

created-at.ts

export class CreatedAt 
    lte: string;
    gte: string;

    constructor(lte: string, gte: string)
        this.lte = lte;
        this.gte = gte;
    ;


好吧,我找到了部分解决方案,我会在这里发布,直到出现更好的答案: 我将嵌套属性提取到单独的查询中并创建我的模型。它并不完美,但它现在正在完成这项工作......

controller.ts

 getAllOrders(
    @Query() query,
    @Query('createdAt[lte]') lte: string, 
    @Query('createdAt[gte]') gte: string): Promise<void>  
    const mappedObject = new QueryParameters(query, lte, gte)
    return this.orderService.findAll(erpCode, mappedObject);

createdAtModel.ts

    export class CreatedAt 
    lte: string;
    gte: string;

    constructor(lte: string, gte: string)
        this.lte = lte;
        this.gte = gte;
    ;

我的模型.ts

import  CreatedAt  from "./created-at";

export class QueryParameters 
    //other keys
    createdAt: CreatedAt;

    constructor(query, lte, gte)
        //other keys
        this.createdAt = new CreatedAt(lte, gte)
    

我确信更好的答案在于使用 NestJS 验证管道,但我没有找到适合我的那个。

【讨论】:

以上是关于如何在 Nestjs 中获取嵌套的 URL 查询的主要内容,如果未能解决你的问题,请参考以下文章

使用@nestjs/graphql 使用@ResolveProperty 和@Resolvers 创建嵌套查询

如何使用 NestJS 创建带参数的嵌套路由

NestJS:无法在 console.log 中获取嵌套对象。错误:类型 Dto 上不存在属性 x

如何在 DTO 中定义 ObjectId 以及在 NestJS Mongoose 中获取关系数据的正确查询是啥?

如何在 NestJS 中编写嵌套 DTO

如何在nestjs mongoose typescript中引用嵌套文档