Eve-Sama
Eve-Sama

Reputation: 2658

How to use query parameters in Nest.js?

I am a freshman in Nest.js.

And my code as below

  @Get('findByFilter/:params')
  async findByFilter(@Query() query): Promise<Article[]> {

  }

I have used postman to test this router

http://localhost:3000/article/findByFilter/bug?google=1&baidu=2

Actually, I can get the query result { google: '1', baidu: '2' }. But I'm not clear why the url has a string 'bug'?

If I delete that word just like

http://localhost:3000/article/findByFilter?google=1&baidu=2

then the postman will shows statusCode 404.

Actually, I don't need the word bug, how to custom the router to realize my destination just like http://localhost:3000/article/findByFilter?google=1&baidu=2

Here's another question is how to make mutiple router point to one method?

Upvotes: 117

Views: 301865

Answers (5)

Dennis R
Dennis R

Reputation: 1937

If you have you parameter as part or url: /articles/${articleId}/details, you wold use @Param

@Get('/articles/:ARTICLE_ID/details')
async getDetails(
    @Param('ARTICLE_ID') articleId: string
)

IF you want to provide query params /article/findByFilter/bug?google=1&baidu=2, you could use

@Get('/article/findByFilter/bug')
async find(
    @Query('google') google: number,
    @Query('baidu') baidu: number,
)

EDIT: The path part (/article/findByFilter/bug) should not have a trailing question mark even when you expect query parameters. When you specify a question mark (like /article/findByFilter/bug?) it makes the last g optional, as this string is treated as a regex.

Upvotes: 83

zemil
zemil

Reputation: 5066

For common case:

getSomeDataRoute(@Query() allQueryParams: { search?: string, page?: string })

// or

getSomeDataRoute(@Query('search') search?: string, @Query('page') page?: string)

For advanced case with dto and transformer:

class QueryDto {
    @Type(() => Number)
    @IsInt()
    public readonly page: number;

    @Type(() => Number)
    @IsInt()
    public readonly take: number;
}

@Injectable()
class QueryTransformPipe implements PipeTransform {
    async transform(value: QueryRequestDto, { metatype }: ArgumentMetadata) {
        if (!metatype) {
            return value;
        }

        return plainToInstance(metatype, value);
    }
}


@Controller()
class YourController {
    @Get()
    // also you can use it with pipe decorator
    // @UsePipes(new QueryTransformPipe())
    async getData(@Query(new QueryTransformPipe()) query?: QueryRequestDto) {
        // here you get instanceof QueryTransformPipe
        // with typeof query.page === 'number' && typeof query.take === 'number'
    }
}

Upvotes: 8

Dmitry Grinko
Dmitry Grinko

Reputation: 15204

We can use @Req()

import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';

(...)

@Get(':framework')
getData(@Req() request: Request): Object {
    return {...request.params, ...request.query};
}

/nest?version=7

{
    "framework": "nest",
    "version": "7"
}

read more

Upvotes: 16

Kim Kern
Kim Kern

Reputation: 60357

Query parameters

You have to remove :params for it to work as expected:

@Get('findByFilter')
async findByFilter(@Query() query): Promise<Article[]> {
  // ...
}

Path parameters

The :param syntax is for path parameters and matches any string on a path:

@Get('products/:id')
getProduct(@Param('id') id) {

matches the routes

localhost:3000/products/1
localhost:3000/products/2abc
// ...

Route wildcards

To match multiple endpoints to the same method you can use route wildcards:

@Get('other|te*st')

will match

localhost:3000/other
localhost:3000/test
localhost:3000/te123st
// ...

Upvotes: 221

H&#237;tallo Willian
H&#237;tallo Willian

Reputation: 21

You can use the @Req decorator, and use param object, see :

@Get()
  findAll(
    @Req() req: Request
  ): Promise<any[]> {
    console.log(req.query);
    // another code ....
  }

Upvotes: 2

Related Questions