119

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?

5 Answers 5

224

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
// ...
Sign up to request clarification or add additional context in comments.

Comments

83

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.

Comments

16

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

2 Comments

I had to put this code... import { Request } from 'express'; ...on top of the script for this to work!
@JonathanMartins Feel free to edit my answer
8

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'
    }
}

Comments

2

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

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

2 Comments

No need to do this, Nest helps you by abstracting a lot of the underlying Express request away: docs.nestjs.com/controllers#request-object
Actually might help when you are creating a proxy and want to transfer the params as is

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.