Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions content/controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export class CatsController {

> info **Hint** To take advantage of `express` typings (like in the `request: Request` parameter example above), make sure to install the `@types/express` package.

The request object represents the HTTP request and contains properties for the query string, parameters, HTTP headers, and body (read more [here](https://expressjs.com/en/api.html#req)). In most cases, you don't need to manually access these properties. Instead, you can use dedicated decorators like `@Body()` or `@Query()`, which are available out of the box. Below is a list of the provided decorators and the corresponding platform-specific objects they represent.
The request object represents the HTTP request and contains properties for the query string, parameters, HTTP headers, and body (read more [here](https://expressjs.com/en/api.html#req)). In most cases, you don't need to manually access these properties. Instead, you can use dedicated decorators like `@Body()` or `@QueryString()`, which are available out of the box. Below is a list of the provided **parameter** decorators and the corresponding platform-specific objects they represent.

<table>
<tbody>
Expand Down Expand Up @@ -130,7 +130,7 @@ The request object represents the HTTP request and contains properties for the q
<td><code>req.body</code> / <code>req.body[key]</code></td>
</tr>
<tr>
<td><code>@Query(key?: string)</code></td>
<td><code>@QueryString(key?: string)</code></td>
<td><code>req.query</code> / <code>req.query[key]</code></td>
</tr>
<tr>
Expand Down Expand Up @@ -189,7 +189,18 @@ export class CatsController {
}
```

It's that simple. Nest provides decorators for all of the standard HTTP methods: `@Get()`, `@Post()`, `@Put()`, `@Delete()`, `@Patch()`, `@Options()`, and `@Head()`. In addition, `@All()` defines an endpoint that handles all of them.
It's that simple. Nest provides decorators for all of the standard HTTP methods: `@Get()`, `@Post()`, `@Put()`, `@Delete()`, `@Patch()`, `@Options()`, and `@Head()`. Nest also provides `@Query()` and `@Search()` for the corresponding HTTP methods. In addition, `@All()` defines an endpoint that handles all of them.

```typescript
@Query('search')
find(@Body() filters: SearchDto) {
return this.service.search(filters);
}
```

> info **Hint** The HTTP `QUERY` method is safe and idempotent and carries a request body; use `@Body()` for the payload (not `@QueryString()`). Runtime support depends on Node.js including `QUERY` in `http.METHODS` (typically `>=20.19.3 <21` or `>=22.2.0`). Express 5 (the default via `@nestjs/platform-express`) exposes `app.query` when Node includes `QUERY`; the Fastify adapter registers the verb via `query(...)`. Client and proxy support may vary.

> warning **Warning** Do not confuse the `@Query()` **method** decorator (HTTP `QUERY` routes) with `@QueryString()`, the **parameter** decorator that extracts URL query string values from `req.query`.

#### Route wildcards

Expand Down Expand Up @@ -256,7 +267,7 @@ Returned values will override any arguments passed to the `@Redirect()` decorato
```typescript
@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
getDocs(@QueryString('version') version) {
if (version && version === '5') {
return { url: 'https://docs.nestjs.com/v5/' };
}
Expand Down Expand Up @@ -408,19 +419,21 @@ async create(createCatDto) {

#### Query parameters

When handling query parameters in your routes, you can use the `@Query()` decorator to extract them from incoming requests. Let's see how this works in practice.
When handling query parameters in your routes, you can use the `@QueryString()` decorator to extract them from incoming requests. Let's see how this works in practice.

> warning **Warning** Previously this was `@Query()`. That name is now reserved for the HTTP `QUERY` **method** decorator. Use `@QueryString()` to read `req.query`.

Consider a route where we want to filter a list of cats based on query parameters like `age` and `breed`. First, define the query parameters in the `CatsController`:

```typescript
@@filename(cats.controller)
@Get()
async findAll(@Query('age') age: number, @Query('breed') breed: string) {
async findAll(@QueryString('age') age: number, @QueryString('breed') breed: string) {
return `This action returns all cats filtered by age: ${age} and breed: ${breed}`;
}
```

In this example, the `@Query()` decorator is used to extract the values of `age` and `breed` from the query string. For example, a request to:
In this example, the `@QueryString()` decorator is used to extract the values of `age` and `breed` from the query string. For example, a request to:

```plaintext
GET /cats?age=2&breed=Persian
Expand Down Expand Up @@ -465,7 +478,7 @@ Below is an example that demonstrates the use of several available decorators to

```typescript
@@filename(cats.controller)
import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { Controller, Get, QueryString, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
Expand All @@ -476,7 +489,7 @@ export class CatsController {
}

@Get()
findAll(@Query() query: ListAllEntities) {
findAll(@QueryString() query: ListAllEntities) {
return `This action returns all cats (limit: ${query.limit} items)`;
}

Expand All @@ -496,7 +509,7 @@ export class CatsController {
}
}
@@switch
import { Controller, Get, Query, Post, Body, Put, Param, Delete, Bind } from '@nestjs/common';
import { Controller, Get, QueryString, Post, Body, Put, Param, Delete, Bind } from '@nestjs/common';

@Controller('cats')
export class CatsController {
Expand All @@ -507,7 +520,7 @@ export class CatsController {
}

@Get()
@Bind(Query())
@Bind(QueryString())
findAll(query) {
console.log(query);
return `This action returns all cats (limit: ${query.limit} items)`;
Expand Down
4 changes: 2 additions & 2 deletions content/custom-decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Nest provides a set of useful **param decorators** that you can use together wit
<td><code>req.body</code> / <code>req.body[param]</code></td>
</tr>
<tr>
<td><code>@Query(param?: string)</code></td>
<td><code>@QueryString(param?: string)</code></td>
<td><code>req.query</code> / <code>req.query[param]</code></td>
</tr>
<tr>
Expand Down Expand Up @@ -156,7 +156,7 @@ You can use this same decorator with different keys to access different properti

#### Working with pipes

Nest treats custom param decorators in the same fashion as the built-in ones (`@Body()`, `@Param()` and `@Query()`). This means that pipes are executed for the custom annotated parameters as well (in our examples, the `user` argument). Moreover, you can apply the pipe directly to the custom decorator:
Nest treats custom param decorators in the same fashion as the built-in ones (`@Body()`, `@Param()` and `@QueryString()`). This means that pipes are executed for the custom annotated parameters as well (in our examples, the `user` argument). Moreover, you can apply the pipe directly to the custom decorator:

```typescript
@@filename()
Expand Down
2 changes: 1 addition & 1 deletion content/faq/request-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class CatsController {
updateCat(
@Body() body: UpdateCatDTO,
@Param() params: UpdateCatParams,
@Query() query: UpdateCatQuery,
@QueryString() query: UpdateCatQuery,
) {
return this.catsService.updateCat(body, params, query);
}
Expand Down
25 changes: 25 additions & 0 deletions content/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,28 @@ $ mau deploy
```

You can learn more about Mau [in this chapter](/deployment#easy-deployment-with-mau).

#### `@Query()` and `@QueryString()`

> warning **BREAKING CHANGE** (NestJS release that introduces HTTP `QUERY` support; see [nestjs/nest#17397](https://github.com/nestjs/nest/pull/17397))
>
> - Rename: `@Query()` parameter decorator → `@QueryString()`
> - New: `@Query()` method decorator routes HTTP `QUERY` requests

The former `@Query()` **parameter** decorator (which extracted URL query string values from `req.query`) has been renamed to `@QueryString()`. The `@Query()` name is now the **method** decorator for the HTTP `QUERY` verb (same pattern as `@Get()`, `@Post()`, `@Search()`, and so on). Handlers for HTTP `QUERY` should read the payload with `@Body()`.

```typescript
// before
@Get()
find(@Query('page') page: string) {}

// after
@Get()
find(@QueryString('page') page: string) {}

// new HTTP QUERY route
@Query('items')
search(@Body() body: FiltersDto) {}
```

> info **Hint** Runtime support for the HTTP `QUERY` method depends on Node.js including `QUERY` in `http.METHODS` (typically `>=20.19.3 <21` or `>=22.2.0`). See [Controllers](/controllers#resources) for more details.
6 changes: 3 additions & 3 deletions content/openapi/types-and-parameters.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
### Types and parameters

The `SwaggerModule` searches for all `@Body()`, `@Query()`, and `@Param()` decorators in route handlers to generate the API document. It also creates corresponding model definitions by taking advantage of reflection. Consider the following code:
The `SwaggerModule` searches for all `@Body()`, `@QueryString()`, and `@Param()` decorators in route handlers to generate the API document. It also creates corresponding model definitions by taking advantage of reflection. Consider the following code:

```typescript
@Post()
Expand Down Expand Up @@ -120,11 +120,11 @@ export enum UserRole {
}
```

You can then use the enum directly with the `@Query()` parameter decorator in combination with the `@ApiQuery()` decorator.
You can then use the enum directly with the `@QueryString()` parameter decorator in combination with the `@ApiQuery()` decorator.

```typescript
@ApiQuery({ name: 'role', enum: UserRole })
async filterByRole(@Query('role') role: UserRole = UserRole.User) {}
async filterByRole(@QueryString('role') role: UserRole = UserRole.User) {}
```

<figure><img src="/assets/enum_query.gif" /></figure>
Expand Down
10 changes: 5 additions & 5 deletions content/pipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ For example with a query string parameter:

```typescript
@Get()
async findOne(@Query('id', ParseIntPipe) id: number) {
async findOne(@QueryString('id', ParseIntPipe) id: number) {
return this.catsService.findOne(id);
}
```
Expand Down Expand Up @@ -165,7 +165,7 @@ These properties describe the currently processed argument.
</td>
<td>Indicates whether the argument is a body
<code>@Body()</code>, query
<code>@Query()</code>, param
<code>@QueryString()</code>, param
<code>@Param()</code>, or a custom parameter (read more
<a routerLink="/custom-decorators">here</a>).</td>
</tr>
Expand Down Expand Up @@ -549,14 +549,14 @@ We leave the implementation of this pipe to the reader, but note that like all o

#### Providing defaults

`Parse*` pipes expect a parameter's value to be defined. They throw an exception upon receiving `null` or `undefined` values. To allow an endpoint to handle missing querystring parameter values, we have to provide a default value to be injected before the `Parse*` pipes operate on these values. The `DefaultValuePipe` serves that purpose. Simply instantiate a `DefaultValuePipe` in the `@Query()` decorator before the relevant `Parse*` pipe, as shown below:
`Parse*` pipes expect a parameter's value to be defined. They throw an exception upon receiving `null` or `undefined` values. To allow an endpoint to handle missing querystring parameter values, we have to provide a default value to be injected before the `Parse*` pipes operate on these values. The `DefaultValuePipe` serves that purpose. Simply instantiate a `DefaultValuePipe` in the `@QueryString()` decorator before the relevant `Parse*` pipe, as shown below:

```typescript
@@filename()
@Get()
async findAll(
@Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
@Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
@QueryString('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
@QueryString('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
) {
return this.catsService.findAll({ activeOnly, page });
}
Expand Down
2 changes: 1 addition & 1 deletion content/techniques/serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ In the example below, despite returning plain JavaScript objects in both conditi
@UseInterceptors(ClassSerializerInterceptor)
@SerializeOptions({ type: UserEntity })
@Get()
findOne(@Query() { id }: { id: number }): UserEntity {
findOne(@QueryString() { id }: { id: number }): UserEntity {
if (id === 1) {
return {
id: 1,
Expand Down
4 changes: 2 additions & 2 deletions content/techniques/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ Alternatively (with auto-transformation disabled), you can explicitly cast value
@Get(':id')
findOne(
@Param('id', ParseIntPipe) id: number,
@Query('sort', ParseBoolPipe) sort: boolean,
@QueryString('sort', ParseBoolPipe) sort: boolean,
) {
console.log(typeof id === 'number'); // true
console.log(typeof sort === 'boolean'); // true
Expand Down Expand Up @@ -420,7 +420,7 @@ In addition, the `ParseArrayPipe` may come in handy when parsing query parameter
```typescript
@Get()
findByIds(
@Query('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
@QueryString('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
ids: number[],
) {
return 'This action returns users by ids';
Expand Down